URL
https://opencores.org/ocsvn/ps2/ps2/trunk
Subversion Repositories ps2
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 41 to Rev 42
- ↔ Reverse comparison
Rev 41 → Rev 42
/tags/rel_13/sim/rtl_sim/bin/rtl_file_list
0,0 → 1,6
ps2_keyboard.v |
ps2_mouse.v |
ps2_top.v |
ps2_translation_table.v |
ps2_wb_if.v |
ps2_io_ctrl.v |
/tags/rel_13/sim/rtl_sim/bin/sim_file_list
0,0 → 1,5
ps2_keyboard_model.v |
ps2_test_bench.v |
wb_master32.v |
wb_master_behavioral.v |
ps2_sim_top.v |
/tags/rel_13/sim/rtl_sim/bin/xilinx_file_list
0,0 → 1,2
RAMB4_S8.v |
glbl.v |
/tags/rel_13/sim/rtl_sim/bin/cds.lib
0,0 → 1,6
# |
# cds.lib: Defines the locations of compiled libraries. |
# Created by ncprep on Wed Aug 1 15:03:54 2001 |
# |
|
define worklib ./INCA_libs/worklib |
/tags/rel_13/sim/rtl_sim/bin/hdl.var
0,0 → 1,9
# |
# hdl.var: Defines variables used by the INCA tools. |
# Created by ncprep on Wed Aug 1 15:03:54 2001 |
# |
|
softinclude $CDS_INST_DIR/tools/inca/files/hdl.var |
|
define LIB_MAP ( $LIB_MAP, + => worklib ) |
define VIEW_MAP ( $VIEW_MAP, .v => v) |
/tags/rel_13/sim/rtl_sim/log/ncelab.log
0,0 → 1,56
TOOL: ncelab 04.10-b001: Started on Nov 30, 2003 at 12:53:31 |
ncelab |
-f ncelab.args |
-MESSAGES |
-NOCOPYRIGHT |
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-LOGFILE ../log/ncelab.log |
-TIMESCALE 1ns/100ps |
-SNAPSHOT worklib.ps2_test_bench:rtl |
-NO_TCHK_MSG |
-ACCESS +RWC |
worklib.ps2_test_bench |
|
Elaborating the design hierarchy: |
Caching library 'worklib' ....... Done |
Building instance overlay tables: .................... Done |
Generating native compiled code: |
worklib.WB_MASTER32:v <0x285dcd5e> |
streams: 14, words: 37673 |
worklib.WB_MASTER_BEHAVIORAL:v <0x4011829a> |
streams: 6, words: 64972 |
worklib.ps2_io_ctrl:v <0x1a9cfb7e> |
streams: 7, words: 4237 |
worklib.ps2_keyboard:v <0x48cda7c5> |
streams: 107, words: 77889 |
worklib.ps2_keyboard_model:v <0x64c1328f> |
streams: 13, words: 19418 |
worklib.ps2_sim_top:v <0x3261324c> |
streams: 4, words: 1087 |
worklib.ps2_test_bench:v <0x1e73bec9> |
streams: 46, words: 159235 |
worklib.ps2_top:v <0x758f909c> |
streams: 3, words: 782 |
worklib.ps2_translation_table:v <0x726febd5> |
streams: 14, words: 9671 |
worklib.ps2_wb_if:v <0x2138f2f1> |
streams: 101, words: 78860 |
Loading native compiled code: .................... Done |
Building instance specific data structures. |
Design hierarchy summary: |
Instances Unique |
Modules: 10 10 |
Primitives: 2 1 |
Registers: 254 254 |
Scalar wires: 74 - |
Expanded wires: 32 1 |
Vectored wires: 16 - |
Always blocks: 41 41 |
Initial blocks: 4 4 |
Parallel blocks: 14 14 |
Cont. assignments: 40 56 |
Pseudo assignments: 5 59 |
Simulation timescale: 1ps |
Writing initial simulation snapshot: worklib.ps2_test_bench:rtl |
TOOL: ncelab 04.10-b001: Exiting on Nov 30, 2003 at 12:53:33 (total: 00:00:02) |
/tags/rel_13/sim/rtl_sim/log/ncvlog.log
0,0 → 1,59
TOOL: ncvlog 04.10-b001: Started on Nov 30, 2003 at 12:53:30 |
ncvlog |
-f ncvlog.args |
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-MESSAGES |
-INCDIR ../../../bench/verilog |
-INCDIR ../../../rtl/verilog |
-NOCOPYRIGHT |
-LOGFILE ../log/ncvlog.log |
-DEFINE PS2_NUM_OF_NORMAL_SCANCODES 85 |
-DEFINE PS2_NUM_OF_EXTENDED_SCANCODES 38 |
-DEFINE SIM |
../../../rtl/verilog/ps2_keyboard.v |
../../../rtl/verilog/ps2_mouse.v |
../../../rtl/verilog/ps2_top.v |
../../../rtl/verilog/ps2_translation_table.v |
../../../rtl/verilog/ps2_wb_if.v |
../../../rtl/verilog/ps2_io_ctrl.v |
../../../bench/verilog/ps2_keyboard_model.v |
../../../bench/verilog/ps2_test_bench.v |
../../../bench/verilog/wb_master32.v |
../../../bench/verilog/wb_master_behavioral.v |
../../../bench/verilog/ps2_sim_top.v |
|
file: ../../../rtl/verilog/ps2_keyboard.v |
module worklib.ps2_keyboard:v |
errors: 0, warnings: 0 |
file: ../../../rtl/verilog/ps2_mouse.v |
module worklib.ps2_mouse:v |
errors: 0, warnings: 0 |
file: ../../../rtl/verilog/ps2_top.v |
module worklib.ps2_top:v |
errors: 0, warnings: 0 |
file: ../../../rtl/verilog/ps2_translation_table.v |
module worklib.ps2_translation_table:v |
errors: 0, warnings: 0 |
file: ../../../rtl/verilog/ps2_wb_if.v |
module worklib.ps2_wb_if:v |
errors: 0, warnings: 0 |
file: ../../../rtl/verilog/ps2_io_ctrl.v |
module worklib.ps2_io_ctrl:v |
errors: 0, warnings: 0 |
file: ../../../bench/verilog/ps2_keyboard_model.v |
module worklib.ps2_keyboard_model:v |
errors: 0, warnings: 0 |
file: ../../../bench/verilog/ps2_test_bench.v |
module worklib.ps2_test_bench:v |
errors: 0, warnings: 0 |
file: ../../../bench/verilog/wb_master32.v |
module worklib.WB_MASTER32:v |
errors: 0, warnings: 0 |
file: ../../../bench/verilog/wb_master_behavioral.v |
module worklib.WB_MASTER_BEHAVIORAL:v |
errors: 0, warnings: 0 |
file: ../../../bench/verilog/ps2_sim_top.v |
module worklib.ps2_sim_top:v |
errors: 0, warnings: 0 |
TOOL: ncvlog 04.10-b001: Exiting on Nov 30, 2003 at 12:53:30 (total: 00:00:00) |
/tags/rel_13/sim/rtl_sim/log/ncsim.log
0,0 → 1,27
TOOL: ncsim 04.10-b001: Started on Nov 30, 2003 at 12:53:34 |
ncsim |
-LICQUEUE |
-f ./ncsim.args |
-MESSAGES |
-NOCOPYRIGHT |
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-INPUT ncsim.tcl |
-LOGFILE ../log/ncsim.log |
worklib.ps2_test_bench:rtl |
|
Loading snapshot worklib.ps2_test_bench:rtl .................... Done |
ncsim> source /shared/tools/ncsim/tools/inca/files/ncsimrc |
ncsim> database -open waves -shm -into ../out/waves.shm |
Created SHM database waves |
ncsim> probe -create -database waves ps2_test_bench -shm -all -depth all |
Created probe 1 |
ncsim> run |
|
|
status: Testbench done |
report (deaddead) |
exit (00000000) |
/projects/highland/gorand/tmp/ps2/bench/verilog/ps2_test_bench.v:289 $finish(0); |
ncsim> quit |
TOOL: ncsim 04.10-b001: Exiting on Nov 30, 2003 at 13:02:41 (total: 00:09:07) |
/tags/rel_13/sim/rtl_sim/run/ncelab.args
0,0 → 1,10
-MESSAGES |
-NOCOPYRIGHT |
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-LOGFILE ../log/ncelab.log |
-TIMESCALE 1ns/100ps |
-SNAPSHOT worklib.ps2_test_bench:rtl |
-NO_TCHK_MSG |
-ACCESS +RWC |
worklib.ps2_test_bench |
/tags/rel_13/sim/rtl_sim/run/ncsim.key
0,0 → 1,10
exit |
/tags/rel_13/sim/rtl_sim/run/ncvlog.args
0,0 → 1,21
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-MESSAGES |
-INCDIR ../../../bench/verilog |
-INCDIR ../../../rtl/verilog |
-NOCOPYRIGHT |
-LOGFILE ../log/ncvlog.log |
-DEFINE "PS2_NUM_OF_NORMAL_SCANCODES 85" |
-DEFINE "PS2_NUM_OF_EXTENDED_SCANCODES 38" |
-DEFINE "SIM" |
../../../rtl/verilog/ps2_keyboard.v |
../../../rtl/verilog/ps2_mouse.v |
../../../rtl/verilog/ps2_top.v |
../../../rtl/verilog/ps2_translation_table.v |
../../../rtl/verilog/ps2_wb_if.v |
../../../rtl/verilog/ps2_io_ctrl.v |
../../../bench/verilog/ps2_keyboard_model.v |
../../../bench/verilog/ps2_test_bench.v |
../../../bench/verilog/wb_master32.v |
../../../bench/verilog/wb_master_behavioral.v |
../../../bench/verilog/ps2_sim_top.v |
/tags/rel_13/sim/rtl_sim/run/ncsim.args
0,0 → 1,7
-MESSAGES |
-NOCOPYRIGHT |
-CDSLIB ../bin/cds.lib |
-HDLVAR ../bin/hdl.var |
-INPUT ncsim.tcl |
-LOGFILE ../log/ncsim.log |
worklib.ps2_test_bench:rtl |
/tags/rel_13/sim/rtl_sim/run/ncsim.tcl
0,0 → 1,4
database -open waves -shm -into ../out/waves.shm |
probe -create -database waves ps2_test_bench -shm -all -depth all |
run |
quit |
/tags/rel_13/sim/rtl_sim/run/run_sim
0,0 → 1,99
#!/bin/csh -f |
|
set current_par = 0 |
set output_waveform = 0 |
while ( $current_par < $# ) |
@ current_par = $current_par + 1 |
case wave: |
@ output_waveform = 1 |
breaksw |
default: |
echo 'Unknown option "'$argv[$current_par]'"!' |
exit |
breaksw |
endsw |
end |
|
echo "-CDSLIB ../bin/cds.lib" > ncvlog.args |
echo "-HDLVAR ../bin/hdl.var" >> ncvlog.args |
echo "-MESSAGES" >> ncvlog.args |
echo "-INCDIR ../../../bench/verilog" >> ncvlog.args |
echo "-INCDIR ../../../rtl/verilog" >> ncvlog.args |
echo "-NOCOPYRIGHT" >> ncvlog.args |
echo "-LOGFILE ../log/ncvlog.log" >> ncvlog.args |
echo '-DEFINE "PS2_NUM_OF_NORMAL_SCANCODES 85"' >> ./ncvlog.args |
echo '-DEFINE "PS2_NUM_OF_EXTENDED_SCANCODES 38"' >> ./ncvlog.args |
echo '-DEFINE "SIM"' >> ./ncvlog.args |
|
|
foreach filename ( `cat ../bin/rtl_file_list` ) |
echo "../../../rtl/verilog/"$filename >> ncvlog.args |
end |
|
foreach filename ( `cat ../bin/sim_file_list` ) |
echo "../../../bench/verilog/"$filename >> ncvlog.args |
end |
|
ncvlog -f ncvlog.args |
|
echo "-MESSAGES" > ncelab.args |
echo "-NOCOPYRIGHT" >> ncelab.args |
echo "-CDSLIB ../bin/cds.lib" >> ncelab.args |
echo "-HDLVAR ../bin/hdl.var" >> ncelab.args |
echo "-LOGFILE ../log/ncelab.log" >> ncelab.args |
echo "-TIMESCALE 1ns/100ps" >> ncelab.args |
echo "-SNAPSHOT worklib.ps2_test_bench:rtl" >> ncelab.args |
echo "-NO_TCHK_MSG" >> ncelab.args |
echo "-ACCESS +RWC" >> ncelab.args |
echo "worklib.ps2_test_bench" >> ncelab.args |
|
ncelab -f ncelab.args |
|
echo "-MESSAGES" > ncsim.args |
echo "-NOCOPYRIGHT" >> ncsim.args |
echo "-CDSLIB ../bin/cds.lib" >> ncsim.args |
echo "-HDLVAR ../bin/hdl.var" >> ncsim.args |
echo "-INPUT ncsim.tcl" >> ncsim.args |
echo "-LOGFILE ../log/ncsim.log" >> ncsim.args |
echo "worklib.ps2_test_bench:rtl" >> ncsim.args |
|
if ( $output_waveform ) then |
echo "database -open waves -shm -into ../out/waves.shm" > ./ncsim.tcl |
echo "probe -create -database waves ps2_test_bench -shm -all -depth all" >> ./ncsim.tcl |
echo "run" >> ./ncsim.tcl |
else |
echo "run" > ./ncsim.tcl |
endif |
|
echo "quit" >> ncsim.tcl |
|
ncsim -LICQUEUE -f ./ncsim.args |
|
set exit_line_nb = `sed -n '/exit/=' < ../log/ncsim.log` |
|
#echo "$exit_line_nb" |
|
set dead_line_nb = 0 |
|
if ( $exit_line_nb ) then |
|
@ dead_line_nb = $exit_line_nb - 1 |
set exit_line=`sed -n $exit_line_nb's/exit/&/gp' < ../log/ncsim.log` |
set dead_line=`sed -n $dead_line_nb's/report/&/gp' < ../log/ncsim.log` |
|
echo "$dead_line" |
echo "$exit_line" |
|
echo "TEST: ps2" |
if ( "$dead_line" == "report (deaddead)" ) then |
if ( "$exit_line" == "exit (00000000)" ) then |
echo "STATUS: passed" #|tee -a ../log/run_sim.log 2>&1 |
else |
echo "STATUS: failed" #|tee -a ../log/run_sim.log 2>&1 |
endif |
else |
echo "STATUS: failed" |
endif |
|
endif |
|
tags/rel_13/sim/rtl_sim/run/run_sim
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/bench/verilog/ps2_test_bench.v
===================================================================
--- tags/rel_13/bench/verilog/ps2_test_bench.v (nonexistent)
+++ tags/rel_13/bench/verilog/ps2_test_bench.v (revision 42)
@@ -0,0 +1,1670 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_test_bench.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.7 2003/10/03 10:16:50 primozs
+// support for configurable devider added
+//
+// Revision 1.6 2003/05/28 16:26:51 simons
+// Change the address width.
+//
+// Revision 1.5 2002/04/09 13:17:03 mihad
+// Mouse interface testcases added
+//
+// Revision 1.4 2002/02/20 16:35:34 mihad
+// Little/big endian changes continued
+//
+// Revision 1.3 2002/02/20 15:20:02 mihad
+// Little/big endian changes incorporated
+//
+// Revision 1.2 2002/02/18 18:08:31 mihad
+// One bug fixed
+//
+// Revision 1.1.1.1 2002/02/18 16:16:55 mihad
+// Initial project import - working
+//
+//
+
+`include "timescale.v"
+`include "ps2_testbench_defines.v"
+`include "ps2_defines.v"
+
+`define KBD_STATUS_REG 32'h64
+`define KBD_CNTL_REG 32'h64
+`define KBD_DATA_REG 32'h60
+/*
+ * controller commands
+ */
+`define KBD_READ_MODE 32'h20_00_00_00
+`define KBD_WRITE_MODE 32'h60_00_00_00
+`define KBD_SELF_TEST 32'hAA_00_00_00
+`define KBD_SELF_TEST2 32'hAB_00_00_00
+`define KBD_CNTL_ENABLE 32'hAE_00_00_00
+/*
+ * keyboard commands
+ */
+`define KBD_ENABLE 32'hF4_00_00_00
+`define KBD_DISABLE 32'hF5_00_00_00
+`define KBD_RESET 32'hFF_00_00_00
+/*
+ * keyboard replies
+ */
+`define KBD_ACK 32'hFA
+`define KBD_POR 32'hAA
+/*
+ * status register bits
+ */
+`define KBD_OBF 32'h01
+`define KBD_IBF 32'h02
+`define KBD_GTO 32'h40
+`define KBD_PERR 32'h80
+/*
+ * keyboard controller mode register bits
+ */
+`define KBD_EKI 32'h01_00_00_00
+`define KBD_SYS 32'h04_00_00_00
+`define KBD_DMS 32'h20_00_00_00
+`define KBD_KCC 32'h40_00_00_00
+`define KBD_DISABLE_COMMAND 32'h10_00_00_00
+`define AUX_OBUF_FULL 8'h20 /* output buffer (from device) full */
+`define AUX_INTERRUPT_ON 32'h02_000000 /* enable controller interrupts */
+
+`ifdef PS2_AUX
+`define AUX_ENABLE 32'ha8_000000 /* enable aux */
+`define AUX_DISABLE 32'ha7_000000 /* disable aux */
+`define AUX_MAGIC_WRITE 32'hd4_000000 /* value to send aux device data */
+`define AUX_SET_SAMPLE 32'hf3_000000 /* set sample rate */
+`define AUX_SET_RES 32'he8_000000 /* set resolution */
+`define AUX_SET_SCALE21 32'he7_000000 /* set 2:1 scaling */
+`define AUX_INTS_OFF 32'h65_000000 /* disable controller interrupts */
+`define AUX_INTS_ON 32'h47_000000 /* enable controller interrupts */
+`define AUX_ENABLE_DEV 32'hf4_000000 /* enable aux device */
+`endif
+
+module ps2_test_bench() ;
+
+parameter [31:0] MAX_SEQUENCE_LENGTH = 10 ;
+wire kbd_clk_cable ;
+wire kbd_data_cable ;
+
+pullup(kbd_clk_cable) ;
+pullup(kbd_data_cable) ;
+
+`ifdef PS2_AUX
+pullup(aux_clk_cable) ;
+pullup(aux_data_cable) ;
+wire wb_intb ;
+reg stop_mouse_tests ;
+`endif
+
+reg wb_clock ;
+reg wb_reset ;
+
+wire [7:0] received_char ;
+wire char_valid ;
+
+reg error ;
+
+`ifdef XILINX
+ assign glbl.GSR = wb_reset ;
+`endif
+ps2_keyboard_model i_ps2_keyboard_model
+(
+ .kbd_clk_io (kbd_clk_cable),
+ .kbd_data_io (kbd_data_cable),
+ .last_char_received_o (received_char),
+ .char_valid_o (char_valid)
+) ;
+
+`ifdef PS2_AUX
+wire [7:0] aux_received_char ;
+ps2_keyboard_model i_ps2_mouse_model
+(
+ .kbd_clk_io (aux_clk_cable),
+ .kbd_data_io (aux_data_cable),
+ .last_char_received_o (aux_received_char),
+ .char_valid_o (aux_char_valid)
+) ;
+`endif
+
+reg ok ;
+reg error1 ;
+
+reg ok_o;
+
+integer rem;
+integer wb_period;
+reg wb_rem;
+reg [15:0] wb_dev_data;
+
+
+integer watchdog_timer ;
+reg watchdog_reset ;
+reg watchdog_reset_previous ;
+
+reg [7:0] normal_scancode_set2_mem [0:`PS2_NUM_OF_NORMAL_SCANCODES - 1] ;
+reg [7:0] normal_scancode_set1_mem [0:`PS2_NUM_OF_NORMAL_SCANCODES - 1] ;
+reg [7:0] extended_scancode_set2_mem [0:`PS2_NUM_OF_EXTENDED_SCANCODES - 1] ;
+reg [7:0] extended_scancode_set1_mem [0:`PS2_NUM_OF_EXTENDED_SCANCODES - 1] ;
+
+`define WB_PERIOD (1/`WB_FREQ)
+initial
+begin
+
+
+ $readmemh("../../../bench/data/normal_scancodes_set2.hex", normal_scancode_set2_mem) ;
+ $readmemh("../../../bench/data/normal_scancodes_set1.hex", normal_scancode_set1_mem) ;
+ $readmemh("../../../bench/data/extended_scancodes_set2.hex", extended_scancode_set2_mem) ;
+ $readmemh("../../../bench/data/extended_scancodes_set1.hex", extended_scancode_set1_mem) ;
+
+
+ wb_period =50;
+ wb_rem = 1'b0;
+ rem =0;
+
+ error1 = 1'b0 ;
+
+ watchdog_timer = 32'h1000_0000 ;
+ watchdog_reset = 0 ;
+ watchdog_reset_previous = 0 ;
+
+ wb_clock = 1'b1 ;
+ wb_reset = 1'b1 ;
+
+ #100 ;
+
+ repeat ( 10 )
+ @(posedge wb_clock) ;
+
+ wb_reset <= 1'b0 ;
+
+ repeat(6)
+
+ begin
+ @(posedge wb_clock)
+ begin
+ rem = 5000 % wb_period;
+
+ if (rem > 0)
+ begin
+ wb_rem = 1'b1;
+
+ end
+ else
+ begin
+ wb_rem = 1'b0;
+
+ end
+ end
+
+ begin
+ devider_write(4'h8,5000/wb_period + wb_rem ,ok_o);
+
+
+ @(posedge wb_clock) ;
+ #1 initialize_controler ;
+
+ test_scan_code_receiving ;
+
+ `ifdef PS2_AUX
+ fork
+ begin
+ `endif
+ test_normal_scancodes ;
+
+ test_extended_scancodes ;
+
+ test_print_screen_and_pause_scancodes ;
+ `ifdef PS2_AUX
+ stop_mouse_tests = 1'b1 ;
+ end
+ begin
+ stop_mouse_tests = 0 ;
+ receive_mouse_movement ;
+ end
+ join
+ `endif
+
+ test_keyboard_inhibit ;
+ wb_period = wb_period + 10 ;
+
+ end
+ end
+ $display("\n\nstatus: Testbench done");
+ if ( error1 == 0 )
+ begin
+ $display ("report (%h)", 32'hdeaddead ) ;
+ $display ("exit (00000000)" ) ;
+ end
+ else
+ begin
+ $display ("report (%h)", 32'heeeeeeee ) ;
+ $display ("exit (00000000)" ) ;
+ end
+
+ $finish(0);
+
+
+ //$display("end simulation");
+ //
+end
+
+always
+ #(wb_period/2.0) wb_clock = !wb_clock ;
+
+wire wb_cyc,
+ wb_stb,
+ wb_we,
+ wb_ack,
+ wb_rty,
+ wb_int ;
+
+wire [3:0] wb_sel ;
+
+wire [31:0] wb_adr, wb_dat_m_s, wb_dat_s_m ;
+
+ps2_sim_top
+i_ps2_top
+(
+ .wb_clk_i (wb_clock),
+ .wb_rst_i (wb_reset),
+ .wb_cyc_i (wb_cyc),
+ .wb_stb_i (wb_stb),
+ .wb_we_i (wb_we),
+ .wb_sel_i (wb_sel),
+ .wb_adr_i (wb_adr[3:0]),
+ .wb_dat_i (wb_dat_m_s),
+ .wb_dat_o (wb_dat_s_m),
+ .wb_ack_o (wb_ack),
+
+ .wb_int_o (wb_int),
+
+ .ps2_kbd_clk_io (kbd_clk_cable),
+ .ps2_kbd_data_io (kbd_data_cable)
+ `ifdef PS2_AUX
+ ,
+ .wb_intb_o(wb_intb),
+
+ .ps2_aux_clk_io(aux_clk_cable),
+ .ps2_aux_data_io(aux_data_cable)
+ `endif
+) ;
+
+WB_MASTER_BEHAVIORAL i_wb_master
+(
+ .CLK_I (wb_clock),
+ .RST_I (wb_reset),
+ .TAG_I (1'b0),
+ .TAG_O (),
+ .ACK_I (wb_ack),
+ .ADR_O (wb_adr),
+ .CYC_O (wb_cyc),
+ .DAT_I (wb_dat_s_m),
+ .DAT_O (wb_dat_m_s),
+ .ERR_I (1'b0),
+ .RTY_I (1'b0),
+ .SEL_O (wb_sel),
+ .STB_O (wb_stb),
+ .WE_O (wb_we),
+ .CAB_O ()
+);
+
+always@(posedge wb_clock)
+begin
+ if ( watchdog_timer === 0 )
+ begin
+ $display("Warning! Simulation watchdog timer has expired!") ;
+ watchdog_timer = 32'hFFFF_FFFF ;
+ end
+ else if ( watchdog_reset !== watchdog_reset_previous )
+ watchdog_timer = 32'hFFFF_FFFF ;
+
+ watchdog_reset_previous = watchdog_reset ;
+
+end
+
+task initialize_controler ;
+ reg [7:0] data ;
+ reg status ;
+begin:main
+
+ // simulate keyboard driver's behaviour
+ data = `KBD_OBF ;
+ status = 1 ;
+ while ( data & `KBD_OBF )
+ begin
+ read_status_reg(data, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data & `KBD_OBF )
+ begin
+ read_data_reg(data, status) ;
+ data = `KBD_OBF ;
+ end
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ end
+
+ kbd_write(`KBD_CNTL_REG, `KBD_SELF_TEST, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // command sent - wait for commands output to be ready
+ data = 0 ;
+ while( !( data & `KBD_OBF ) )
+ begin
+ read_status_reg(data, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+ end
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== 8'h55 )
+ begin
+ $display("Error! Keyboard controler should respond to self test command with hard coded value 0x55! ") ;
+ error1 = 1'b1 ;
+
+ end
+
+ // perform self test 2
+ kbd_write(`KBD_CNTL_REG, `KBD_SELF_TEST2, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // command sent - wait for commands output to be ready
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== 8'h00 )
+ begin
+ $display("Error! Keyboard controler should respond to self test command 2 with hard coded value 0x00! ") ;
+ error1 = 1'b1 ;
+
+ end
+
+ kbd_write(`KBD_CNTL_REG, `KBD_CNTL_ENABLE, status);
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // send reset command to keyboard
+ kbd_write(`KBD_DATA_REG, `KBD_RESET, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ fork
+ begin
+ // wait for keyboard to respond with acknowledge
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== `KBD_ACK )
+ begin
+ $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
+ error1 = 1'b1 ;
+
+ end
+
+ // wait for keyboard to respond with BAT status
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== `KBD_POR )
+ begin
+ $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_POR, data ) ;
+ error1 = 1'b1 ;
+
+ end
+
+ // send disable command to keyboard
+ kbd_write(`KBD_DATA_REG, `KBD_DISABLE, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // wait for keyboard to respond with acknowledge
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== `KBD_ACK )
+ begin
+ $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
+ error1 = 1'b1 ;
+
+ end
+
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, status);
+ if ( status !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, status);
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // send disable command to keyboard
+ kbd_write(`KBD_DATA_REG, `KBD_ENABLE, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // wait for keyboard to respond with acknowledge
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg( data, status ) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( data !== `KBD_ACK )
+ begin
+ $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
+ error1 = 1'b1 ;
+
+ end
+
+ // now check if command byte is as expected
+ kbd_write(`KBD_CNTL_REG, `KBD_READ_MODE, status);
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 0 ;
+ while( status && !( data & `KBD_OBF ) )
+ read_status_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ read_data_reg(data, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ if ( ({data, 24'h0} & (`KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC)) !== (`KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC) )
+ begin
+ $display("Error! Read command byte returned wrong value!") ;
+ error1 = 1'b1 ;
+
+ end
+ end
+ begin
+ @(char_valid) ;
+ if ( {received_char, 24'h0} !== `KBD_RESET )
+ begin
+ $display("Error! Keyboard received invalid character/command") ;
+ error1 = 1'b1 ;
+
+ end
+
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ `KBD_ACK,
+ ok,
+ error
+ ) ;
+
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ `KBD_POR,
+ ok,
+ error
+ ) ;
+
+ @(char_valid) ;
+ if ( {received_char,24'h0} !== `KBD_DISABLE )
+ begin
+ $display("Error! Keyboard received invalid character/command") ;
+ error1 = 1'b1 ;
+
+ end
+
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ `KBD_ACK,
+ ok,
+ error
+ ) ;
+
+ @(char_valid) ;
+ if ( {received_char,24'h0} !== `KBD_ENABLE )
+ begin
+ $display("Error! Keyboard received invalid character/command") ;
+ error1 = 1'b1 ;
+
+ end
+
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ `KBD_ACK,
+ ok,
+ error
+ ) ;
+
+ end
+ join
+
+ watchdog_reset = !watchdog_reset ;
+
+ `ifdef PS2_AUX
+ kbd_write(`KBD_CNTL_REG, `AUX_ENABLE, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ // simulate aux driver's behaviour
+ data = 1 ;
+ status = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_SET_SAMPLE, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ @(aux_char_valid) ;
+ if ( {aux_received_char, 24'h000000} !== `AUX_SET_SAMPLE)
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", `AUX_SET_SAMPLE, aux_received_char ) ;
+ end
+
+ data = 1 ;
+ status = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_SET_RES, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+
+ @(aux_char_valid) ;
+ if ( {aux_received_char, 24'h000000} !== `AUX_SET_RES )
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", `AUX_SET_RES, aux_received_char ) ;
+ end
+
+ data = 1 ;
+ status = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, {8'd100, 24'h000000}, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ @(aux_char_valid) ;
+ if ( aux_received_char !== 8'd100 )
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", 100, aux_received_char ) ;
+ end
+
+ data = 1 ;
+ status = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, {8'd3, 24'h000000}, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+
+ @(aux_char_valid) ;
+ if ( aux_received_char !== 8'd3 )
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", 3, aux_received_char ) ;
+ end
+
+ data = 1 ;
+ status = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_SET_SCALE21, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ @(aux_char_valid) ;
+ if ( {aux_received_char, 24'h000000} !== `AUX_SET_SCALE21)
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", `AUX_SET_SCALE21, aux_received_char ) ;
+ end
+
+ kbd_write(`KBD_CNTL_REG, `AUX_DISABLE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_INTS_OFF, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_ENABLE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_CNTL_REG, `AUX_MAGIC_WRITE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ data = 1 ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_ENABLE_DEV, status) ;
+
+ if ( status !== 1 )
+ #1 disable main ;
+
+ @(aux_char_valid) ;
+ if ( {aux_received_char, 24'h000000} !== `AUX_ENABLE_DEV)
+ begin
+ $display("Time %t ", $time) ;
+ $display("PS2 mouse didn't receive expected character! Expected %h, actual %h !", `AUX_ENABLE_DEV, aux_received_char ) ;
+ end
+
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `AUX_INTS_ON, status) ;
+ if ( status !== 1 )
+ #1 disable main ;
+
+ watchdog_reset = !watchdog_reset ;
+ `endif
+
+end
+endtask // initialize_controler
+
+task read_data_reg ;
+ output [7:0] return_byte_o ;
+ output ok_o ;
+ reg `READ_STIM_TYPE read_data ;
+ reg `READ_RETURN_TYPE read_status ;
+ reg `WB_TRANSFER_FLAGS flags ;
+ reg in_use ;
+begin:main
+ if ( in_use === 1 )
+ begin
+ $display("Task read_data_reg re-entered! Time %t", $time) ;
+ #1 disable main ;
+ end
+ else
+ in_use = 1 ;
+
+ ok_o = 1 ;
+ flags`WB_TRANSFER_SIZE = 1 ;
+ flags`WB_TRANSFER_AUTO_RTY = 0 ;
+ flags`WB_TRANSFER_CAB = 0 ;
+ flags`INIT_WAITS = 0 ;
+ flags`SUBSEQ_WAITS = 0 ;
+
+ read_data`READ_ADDRESS = `KBD_DATA_REG ;
+ read_data`READ_SEL = 4'h8 ;
+
+ read_status = 0 ;
+
+ i_wb_master.wb_single_read( read_data, flags, read_status ) ;
+
+ if ( read_status`CYC_ACK !== 1'b1 )
+ begin
+ $display("Error! Keyboard controler didn't acknowledge single read access!") ;
+
+ ok_o = 0 ;
+ end
+ else
+ return_byte_o = read_status`READ_DATA ;
+
+ in_use = 0 ;
+
+end
+endtask //read_data_reg
+
+task read_status_reg ;
+ output [7:0] return_byte_o ;
+ output ok_o ;
+ reg `READ_STIM_TYPE read_data ;
+ reg `READ_RETURN_TYPE read_status ;
+ reg `WB_TRANSFER_FLAGS flags ;
+ reg in_use ;
+begin:main
+ if ( in_use === 1 )
+ begin
+ $display("Task read_status_reg re-entered! Time %t !", $time) ;
+ #1 disable main ;
+ end
+ else
+ in_use = 1 ;
+
+ ok_o = 1 ;
+ flags`WB_TRANSFER_SIZE = 1 ;
+ flags`WB_TRANSFER_AUTO_RTY = 0 ;
+ flags`WB_TRANSFER_CAB = 0 ;
+ flags`INIT_WAITS = 0 ;
+ flags`SUBSEQ_WAITS = 0 ;
+
+ read_data`READ_ADDRESS = `KBD_STATUS_REG ;
+ read_data`READ_SEL = 4'h8 ;
+
+ read_status = 0 ;
+
+ i_wb_master.wb_single_read( read_data, flags, read_status ) ;
+
+ if ( read_status`CYC_ACK !== 1'b1 )
+ begin
+ $display("Error! Keyboard controler didn't acknowledge single read access!") ;
+ error1 = 1'b1 ;
+
+ ok_o = 0 ;
+ end
+ else
+ return_byte_o = read_status`READ_DATA ;
+
+ in_use = 0 ;
+end
+endtask // read_status_reg
+
+task kbd_write ;
+ input [31:0] address_i ;
+ input [31:0] data_i ;
+ output ok_o ;
+
+ reg `WRITE_STIM_TYPE write_data ;
+ reg `WRITE_RETURN_TYPE write_status ;
+ reg `WB_TRANSFER_FLAGS flags ;
+ reg [7:0] kbd_status ;
+begin:main
+ ok_o = 1 ;
+ flags`WB_TRANSFER_SIZE = 1 ;
+ flags`WB_TRANSFER_AUTO_RTY = 0 ;
+ flags`WB_TRANSFER_CAB = 0 ;
+ flags`INIT_WAITS = 0 ;
+ flags`SUBSEQ_WAITS = 0 ;
+
+ write_data`WRITE_ADDRESS = address_i ;
+ write_data`WRITE_DATA = data_i ;
+ write_data`WRITE_SEL = 4'h8 ;
+
+ read_status_reg(kbd_status, ok_o) ;
+
+ while( ok_o && ( kbd_status & `KBD_IBF ))
+ begin
+ read_status_reg(kbd_status, ok_o) ;
+ end
+
+ if ( ok_o !== 1 )
+ #1 disable main ;
+
+ i_wb_master.wb_single_write( write_data, flags, write_status ) ;
+
+ if ( write_status`CYC_ACK !== 1 )
+ begin
+ $display("Error! Keyboard controller didn't acknowledge single write access") ;
+ error1 = 1'b1 ;
+
+ ok_o = 0 ;
+ end
+end
+endtask // kbd_write
+
+task devider_write ;
+ input [31:0] address_i ;
+ input [31:16] data_i ;
+ output ok_o ;
+
+ reg `WRITE_STIM_TYPE write_data ;
+ reg `WRITE_RETURN_TYPE write_status ;
+ reg `WB_TRANSFER_FLAGS flags ;
+begin:main
+ ok_o = 1 ;
+ flags`WB_TRANSFER_SIZE = 1 ;
+ flags`WB_TRANSFER_AUTO_RTY = 0 ;
+ flags`WB_TRANSFER_CAB = 0 ;
+ flags`INIT_WAITS = 0 ;
+ flags`SUBSEQ_WAITS = 0 ;
+
+ write_data`WRITE_ADDRESS = address_i ;
+ write_data`WRITE_DATA = {2{data_i}};
+ write_data`WRITE_SEL = 4'hC ;
+
+ i_wb_master.wb_single_write( write_data, flags, write_status ) ;
+
+ if ( write_status`CYC_ACK !== 1 )
+ begin
+ $display("Error! Keyboard controller didn't acknowledge single write access") ;
+ error1 = 1'b1 ;
+
+ ok_o = 0 ;
+ end
+end
+endtask // devider_write
+
+task test_scan_code_receiving ;
+ reg ok_keyboard ;
+ reg ok_controler ;
+ reg ok ;
+ reg [7:0] data ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
+begin:main
+ // prepare character sequence to send from keyboard to controler
+ // L SHIFT make
+ keyboard_sequence[7:0] = 8'h12 ;
+ // A make
+ keyboard_sequence[15:8] = 8'h1C ;
+ // A break
+ keyboard_sequence[23:16] = 8'hF0 ;
+ keyboard_sequence[31:24] = 8'h1C ;
+ // L SHIFT break
+ keyboard_sequence[39:32] = 8'hF0 ;
+ keyboard_sequence[47:40] = 8'h12 ;
+
+ // prepare character sequence as it is received in scan code set 1 through the controler
+ // L SHIFT make
+ controler_sequence[7:0] = 8'h2A ;
+ // A make
+ controler_sequence[15:8] = 8'h1E ;
+ // A break
+ controler_sequence[23:16] = 8'h9E ;
+ // L SHIFT break
+ controler_sequence[31:24] = 8'hAA ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 4, ok_controler ) ;
+
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ // test same thing with translation disabled!
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ // since translation is disabled, controler sequence is the same as keyboard sequence
+ controler_sequence = keyboard_sequence ;
+
+ fork
+ begin
+
+ send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+
+ end
+ begin
+ receive_sequence( controler_sequence, 6, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ // turn translation on again
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ // test extended character receiving - rctrl + s combination
+ // prepare sequence to send from keyboard to controler
+ // R CTRL make
+ keyboard_sequence[7:0] = 8'hE0 ;
+ keyboard_sequence[15:8] = 8'h14 ;
+ // S make
+ keyboard_sequence[23:16] = 8'h1B ;
+ // S break
+ keyboard_sequence[31:24] = 8'hF0 ;
+ keyboard_sequence[39:32] = 8'h1B ;
+ // R CTRL break
+ keyboard_sequence[47:40] = 8'hE0 ;
+ keyboard_sequence[55:48] = 8'hF0 ;
+ keyboard_sequence[63:56] = 8'h14 ;
+
+ // prepare sequence that should be received from the controler
+ // R CTRL make
+ controler_sequence[7:0] = 8'hE0 ;
+ controler_sequence[15:8] = 8'h1D ;
+ // S make
+ controler_sequence[23:16] = 8'h1F ;
+ // S break
+ controler_sequence[31:24] = 8'h9F ;
+ // R CTRL break
+ controler_sequence[39:32] = 8'hE0 ;
+ controler_sequence[47:40] = 8'h9D ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+
+ receive_sequence( controler_sequence, 6, ok_controler ) ;
+
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ // test same thing with translation disabled!
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ // since translation is disabled, controler sequence is the same as keyboard sequence
+ controler_sequence = keyboard_sequence ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+
+ receive_sequence( controler_sequence, 8, ok_controler ) ;
+
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ watchdog_reset = !watchdog_reset ;
+end
+endtask // test_scan_code_receiving
+
+task test_normal_scancodes ;
+ reg ok ;
+ reg ok_keyboard ;
+ reg ok_controler ;
+ integer i ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
+begin:main
+ // turn translation on
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ for ( i = 0 ; i < `PS2_NUM_OF_NORMAL_SCANCODES ; i = i + 1 )
+ begin
+ keyboard_sequence[7:0] = normal_scancode_set2_mem[i] ;
+ keyboard_sequence[15:8] = 8'hF0 ;
+ keyboard_sequence[23:16] = normal_scancode_set2_mem[i] ;
+
+ controler_sequence[7:0] = normal_scancode_set1_mem[i] ;
+ controler_sequence[15:8] = normal_scancode_set1_mem[i] | 8'h80 ;
+ fork
+ begin
+ send_sequence( keyboard_sequence, 3, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 2, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+ end
+
+ watchdog_reset = !watchdog_reset ;
+
+end
+endtask // test_normal_scancodes
+
+task test_extended_scancodes ;
+ reg ok ;
+ reg ok_keyboard ;
+ reg ok_controler ;
+ integer i ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
+begin:main
+ // turn translation on
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ for ( i = 0 ; i < `PS2_NUM_OF_EXTENDED_SCANCODES ; i = i + 1 )
+ begin
+ keyboard_sequence[7:0] = 8'hE0 ;
+ keyboard_sequence[15:8] = extended_scancode_set2_mem[i] ;
+ keyboard_sequence[23:16] = 8'hE0 ;
+ keyboard_sequence[31:24] = 8'hF0 ;
+ keyboard_sequence[39:32] = extended_scancode_set2_mem[i] ;
+
+ controler_sequence[7:0] = 8'hE0 ;
+ controler_sequence[15:8] = extended_scancode_set1_mem[i] ;
+ controler_sequence[23:16] = 8'hE0 ;
+ controler_sequence[31:24] = extended_scancode_set1_mem[i] | 8'h80 ;
+ fork
+ begin
+ send_sequence( keyboard_sequence, 5, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 4, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+ end
+
+ watchdog_reset = !watchdog_reset ;
+
+end
+endtask // test_extended_scancodes
+
+task return_scan_code_on_irq ;
+ output [7:0] scan_code_o ;
+ output ok_o ;
+ reg [7:0] temp_data ;
+begin:main
+ wait ( wb_int === 1 ) ;
+ read_status_reg( temp_data, ok_o ) ;
+
+ if ( ok_o !== 1'b1 )
+ #1 disable main ;
+
+ if ( !( temp_data & `KBD_OBF ) )
+ begin
+ $display("Error! Interrupt received from keyboard controler when OBF status not set!") ;
+ error1 = 1'b1 ;
+
+ end
+
+ if ( temp_data & `AUX_OBUF_FULL )
+ begin
+ $display("Error! Interrupt received from keyboard controler when AUX_OBUF_FULL status was set!") ;
+ error1 = 1'b1 ;
+
+ end
+
+ read_data_reg( temp_data, ok_o ) ;
+
+ if ( ok_o !== 1'b1 )
+ #1 disable main ;
+
+ scan_code_o = temp_data ;
+end
+endtask // return_scan_code_on_irq
+
+task send_sequence ;
+ input [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] sequence_i ;
+ input [31:0] num_of_chars_i ;
+ output ok_o ;
+ reg [7:0] current_char ;
+ integer i ;
+ reg ok ;
+ reg error ;
+begin:main
+
+ error = 0 ;
+ ok_o = 1 ;
+ ok = 0 ;
+
+ for( i = 0 ; i < num_of_chars_i ; i = i + 1 )
+ begin
+ current_char = sequence_i[7:0] ;
+
+ sequence_i = sequence_i >> 8 ;
+ ok = 0 ;
+ error = 0 ;
+ while ( (ok !== 1) && (error === 0) )
+ begin
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ current_char,
+ ok,
+ error
+ ) ;
+ end
+
+ if ( error )
+ begin
+ $display("Time %t", $time) ;
+ $display("Keyboard model signaled an error!") ;
+ ok_o = 0 ;
+ #1 disable main ;
+ end
+ end
+end
+endtask // send_sequence
+
+task receive_sequence ;
+ input [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] sequence_i ;
+ input [31:0] num_of_chars_i ;
+ output ok_o ;
+ reg [7:0] current_char ;
+ reg [7:0] data ;
+ integer i ;
+begin:main
+
+ ok_o = 1 ;
+
+ for( i = 0 ; i < num_of_chars_i ; i = i + 1 )
+ begin
+ current_char = sequence_i[7:0] ;
+
+ sequence_i = sequence_i >> 8 ;
+
+ return_scan_code_on_irq( data, ok_o ) ;
+
+ if ( ok_o !== 1 )
+ #1 disable main ;
+
+ if ( data !== current_char )
+ begin
+ $display("Time %t", $time) ;
+ $display("Error! Character received was wrong!") ;
+ $display("Expected character: %h, received %h ", current_char, data ) ;
+ end
+ end
+end
+endtask // receive_seqence
+
+task test_keyboard_inhibit ;
+ reg ok_controler ;
+ reg ok_keyboard ;
+ reg error ;
+ reg [7:0] data ;
+begin:main
+ // first test, if keyboard stays inhibited after character is received, but not read from the controler
+
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ 8'hE0,
+ ok_keyboard,
+ error
+ ) ;
+
+ if ( error )
+ begin
+ $display("Error! Keyboard signaled an error while sending character!") ;
+ #1 disable main ;
+ end
+
+ if ( !ok_keyboard )
+ begin
+ $display("Something is wrong! Keyboard wasn't able to send a character!") ;
+ #1 disable main ;
+ end
+
+ // wait 5 us to see, if keyboard is inhibited
+ #60000 ;
+
+ // now check, if clock line is low!
+ if ( kbd_clk_cable !== 0 )
+ begin
+ $display("Error! Keyboard wasn't inhibited when output buffer was filled!") ;
+ #1 disable main ;
+ end
+
+ // now read the character from input buffer and check if clock was released
+ return_scan_code_on_irq( data, ok_controler ) ;
+ if ( ok_controler !== 1'b1 )
+ #1 disable main ;
+
+ if ( data !== 8'hE0 )
+ begin
+ $display("Time %t", $time) ;
+ $display("Error! Character read from controler not as expected!") ;
+ end
+
+ fork
+ begin
+ repeat(10)
+ @(posedge wb_clock) ;
+
+ if ( kbd_clk_cable !== 1 )
+ begin
+ $display("Error! Keyboard wasn't released from inhibited state when output buffer was read!") ;
+ #1 disable main ;
+ end
+ end
+ begin
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ 8'h1C,
+ ok_keyboard,
+ error
+ ) ;
+ if ( !ok_keyboard )
+ begin
+ $display("Something is wrong! Keyboard wasn't able to send a character!") ;
+ #1 disable main ;
+ end
+ end
+ begin
+ return_scan_code_on_irq( data, ok_controler ) ;
+ if ( ok_controler !== 1'b1 )
+ #1 disable main ;
+
+ if ( data !== 8'h1E )
+ begin
+ $display("Time %t", $time) ;
+ $display("Error! Character read from controler not as expected!") ;
+ end
+ end
+ join
+
+ // disable keyboard controler
+ kbd_write( `KBD_CNTL_REG, `KBD_WRITE_MODE, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC | `KBD_DISABLE_COMMAND, ok_controler);
+
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ repeat( 5 )
+ @(posedge wb_clock) ;
+
+ // now check, if clock line is high!
+ if ( kbd_clk_cable !== 1 )
+ begin
+ $display("Error! Keyboard is not supposed to be inhibited when keyboard controler is disabled!") ;
+ #1 disable main ;
+ end
+
+ // send character and enable keyboard controler at the same time
+ fork
+ begin
+ i_ps2_keyboard_model.kbd_send_char
+ (
+ 8'hE0,
+ ok_keyboard,
+ error
+ ) ;
+
+ if ( !ok_keyboard )
+ begin
+ $display("Something is wrong! Keyboard wasn't able to send a character!") ;
+ #1 disable main ;
+ end
+ end
+ begin
+ // enable keyboard controler
+ kbd_write( `KBD_CNTL_REG, `KBD_WRITE_MODE, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC, ok_controler);
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ begin
+ return_scan_code_on_irq( data, ok_controler ) ;
+ if ( ok_controler !== 1'b1 )
+ #1 disable main ;
+
+ if ( data !== 8'hE0 )
+ begin
+ $display("Time %t", $time) ;
+ $display("Error! Character read from controler not as expected!") ;
+ end
+ end
+ join
+
+ // do D2 command, that copies parameter in input buffer to output buffer
+ kbd_write( `KBD_CNTL_REG, 32'hD2_00_00_00, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, 32'h5555_5555, ok_controler) ;
+
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ return_scan_code_on_irq( data, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+
+ if ( data !== 8'h55 )
+ begin
+ $display("Error! D2 command doesn't work properly") ;
+ end
+
+end
+endtask // test_keyboard_inhibit
+
+task test_print_screen_and_pause_scancodes ;
+ reg ok ;
+ reg ok_keyboard ;
+ reg ok_controler ;
+ integer i ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
+ reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
+begin:main
+ // turn translation on
+ kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`AUX_INTERRUPT_ON|`KBD_KCC, ok);
+ if ( ok !== 1 )
+ #1 disable main ;
+
+ // prepare character sequence to send from keyboard to controler - pause
+ keyboard_sequence[7:0] = 8'hE1 ;
+ keyboard_sequence[15:8] = 8'h14 ;
+ keyboard_sequence[23:16] = 8'h77 ;
+ keyboard_sequence[31:24] = 8'hE1 ;
+ keyboard_sequence[39:32] = 8'hF0 ;
+ keyboard_sequence[47:40] = 8'h14 ;
+ keyboard_sequence[55:48] = 8'hF0 ;
+ keyboard_sequence[63:56] = 8'h77 ;
+
+ // prepare character sequence as it is received in scan code set 1 through the controler
+ controler_sequence[7:0] = 8'hE1 ;
+ controler_sequence[15:8] = 8'h1D ;
+ controler_sequence[23:16] = 8'h45 ;
+ controler_sequence[31:24] = 8'hE1 ;
+ controler_sequence[39:32] = 8'h9D ;
+ controler_sequence[47:40] = 8'hC5 ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 6, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ // prepare character sequence to send from keyboard to controler - make print screen
+ keyboard_sequence[7:0] = 8'hE0 ;
+ keyboard_sequence[15:8] = 8'h12 ;
+ keyboard_sequence[23:16] = 8'hE0 ;
+ keyboard_sequence[31:24] = 8'h7C ;
+
+ // prepare character sequence as it is received in scan code set 1 through the controler
+ controler_sequence[7:0] = 8'hE0 ;
+ controler_sequence[15:8] = 8'h2A ;
+ controler_sequence[23:16] = 8'hE0 ;
+ controler_sequence[31:24] = 8'h37 ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 4, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 4, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+
+ // prepare character sequence to send from keyboard to controler - break print screen
+ keyboard_sequence[7:0] = 8'hE0 ;
+ keyboard_sequence[15:8] = 8'hF0 ;
+ keyboard_sequence[23:16] = 8'h7C ;
+ keyboard_sequence[31:24] = 8'hE0 ;
+ keyboard_sequence[39:32] = 8'hF0 ;
+ keyboard_sequence[47:40] = 8'h12 ;
+
+ // prepare character sequence as it is received in scan code set 1 through the controler
+ controler_sequence[7:0] = 8'hE0 ;
+ controler_sequence[15:8] = 8'hB7 ;
+ controler_sequence[23:16] = 8'hE0 ;
+ controler_sequence[31:24] = 8'hAA ;
+
+ fork
+ begin
+ send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
+ if ( ok_keyboard !== 1 )
+ #1 disable main ;
+ end
+ begin
+ receive_sequence( controler_sequence, 4, ok_controler ) ;
+ if ( ok_controler !== 1 )
+ #1 disable main ;
+ end
+ join
+end
+endtask // test_print_screen_and_pause_scancodes
+
+`ifdef PS2_AUX
+task receive_mouse_movement;
+ reg [7:0] mouse_data_received ;
+ reg ok_mouse ;
+ reg ok_wb ;
+ reg error ;
+ integer num_of_mouse_data_sent ;
+begin:main
+ error = 0 ;
+ num_of_mouse_data_sent = 0 ;
+ while ( !stop_mouse_tests )
+ begin
+ fork
+ begin
+ ok_mouse = 0 ;
+ while ( !ok_mouse && !error )
+ begin
+ i_ps2_mouse_model.kbd_send_char
+ (
+ num_of_mouse_data_sent[7:0],
+ ok_mouse,
+ error
+ ) ;
+ end
+ if ( error )
+ begin
+ $display("Mouse model signaled an error while transmiting data! Time %t", $time) ;
+ #1 disable main ;
+ end
+ else
+ num_of_mouse_data_sent = num_of_mouse_data_sent + 1 ;
+
+ end
+ begin
+ return_mouse_data_on_irq( mouse_data_received, ok_wb ) ;
+ if ( !ok_wb )
+ #1 disable main ;
+
+ if ( mouse_data_received !== num_of_mouse_data_sent[7:0] )
+ begin
+ $display("Time %t", $time) ;
+ $display("Data received from mouse has unexpected value! Expected %h, actual %h", num_of_mouse_data_sent[7:0], mouse_data_received) ;
+ end
+ end
+ join
+ end
+
+ $display("Number of chars received from mouse %d", num_of_mouse_data_sent) ;
+end
+endtask //receive_mouse_movement
+
+task return_mouse_data_on_irq ;
+ output [7:0] mouse_data_o ;
+ output ok_o ;
+ reg [7:0] temp_data ;
+begin:main
+ wait ( wb_intb === 1 ) ;
+
+ wait ( ps2_test_bench.read_status_reg.in_use !== 1'b1 );
+
+ read_status_reg( temp_data, ok_o ) ;
+
+ if ( ok_o !== 1'b1 )
+ #1 disable main ;
+
+ if ( !( temp_data & `AUX_OBUF_FULL ) || !(temp_data & `KBD_OBF))
+ begin
+ $display("Error! Interrupt b received from controler when AUX_OBF status or KBD_OBF statuses not set!") ;
+
+ end
+
+ wait ( ps2_test_bench.read_data_reg.in_use !== 1'b1 );
+
+ read_data_reg( temp_data, ok_o ) ;
+
+ if ( ok_o !== 1'b1 )
+ #1 disable main ;
+
+ mouse_data_o = temp_data ;
+end
+endtask // return_scan_code_on_irq
+`endif
+
+endmodule // ps2_test_bench
Index: tags/rel_13/bench/verilog/ps2_sim_top.v
===================================================================
--- tags/rel_13/bench/verilog/ps2_sim_top.v (nonexistent)
+++ tags/rel_13/bench/verilog/ps2_sim_top.v (revision 42)
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_sim_top.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.4 2003/07/01 12:33:45 mihad
+// Added an option to use constant values instead of RAM
+// in the translation table.
+//
+// Revision 1.3 2003/05/28 16:26:51 simons
+// Change the address width.
+//
+// Revision 1.2 2002/04/09 13:16:04 mihad
+// Mouse interface added
+//
+// Revision 1.1.1.1 2002/02/18 16:16:55 mihad
+// Initial project import - working
+//
+//
+
+`include "ps2_defines.v"
+module ps2_sim_top
+(
+ wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i,
+ wb_sel_i,
+ wb_adr_i,
+ wb_dat_i,
+ wb_dat_o,
+ wb_ack_o,
+
+ wb_int_o,
+
+ ps2_kbd_clk_io,
+ ps2_kbd_data_io
+
+ `ifdef PS2_AUX
+ ,
+ wb_intb_o,
+
+ ps2_aux_clk_io,
+ ps2_aux_data_io
+ `endif
+) ;
+
+input wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i ;
+
+input [3:0] wb_sel_i ;
+
+input [3:0] wb_adr_i ;
+input [31:0] wb_dat_i ;
+
+output [31:0] wb_dat_o ;
+
+output wb_ack_o,
+ wb_int_o ;
+
+inout ps2_kbd_clk_io,
+ ps2_kbd_data_io ;
+`ifdef PS2_AUX
+output wb_intb_o ;
+inout ps2_aux_clk_io ;
+inout ps2_aux_data_io ;
+`endif
+
+wire ps2_kbd_clk_pad_i = ps2_kbd_clk_io ;
+wire ps2_kbd_data_pad_i = ps2_kbd_data_io ;
+
+wire ps2_kbd_clk_pad_o,
+ ps2_kbd_data_pad_o,
+ ps2_kbd_clk_pad_oe_o,
+ ps2_kbd_data_pad_oe_o ;
+
+ps2_top i_ps2_top
+(
+ .wb_clk_i (wb_clk_i),
+ .wb_rst_i (wb_rst_i),
+ .wb_cyc_i (wb_cyc_i),
+ .wb_stb_i (wb_stb_i),
+ .wb_we_i (wb_we_i),
+ .wb_sel_i (wb_sel_i),
+ .wb_adr_i (wb_adr_i),
+ .wb_dat_i (wb_dat_i),
+ .wb_dat_o (wb_dat_o),
+ .wb_ack_o (wb_ack_o),
+
+ .wb_int_o (wb_int_o),
+
+ .ps2_kbd_clk_pad_i (ps2_kbd_clk_pad_i),
+ .ps2_kbd_data_pad_i (ps2_kbd_data_pad_i),
+ .ps2_kbd_clk_pad_o (ps2_kbd_clk_pad_o),
+ .ps2_kbd_data_pad_o (ps2_kbd_data_pad_o),
+ .ps2_kbd_clk_pad_oe_o (ps2_kbd_clk_pad_oe_o),
+ .ps2_kbd_data_pad_oe_o (ps2_kbd_data_pad_oe_o)
+
+ `ifdef PS2_AUX
+ ,
+ .wb_intb_o (wb_intb_o),
+
+ .ps2_aux_clk_pad_i (ps2_aux_clk_io),
+ .ps2_aux_data_pad_i (ps2_aux_data_io),
+ .ps2_aux_clk_pad_o (ps2_aux_clk_pad_o),
+ .ps2_aux_data_pad_o (ps2_aux_data_pad_o),
+ .ps2_aux_clk_pad_oe_o (ps2_aux_clk_pad_oe_o),
+ .ps2_aux_data_pad_oe_o (ps2_aux_data_pad_oe_o)
+ `endif
+) ;
+
+assign ps2_kbd_clk_io = ps2_kbd_clk_pad_oe_o ? ps2_kbd_clk_pad_o : 1'bz ;
+assign ps2_kbd_data_io = ps2_kbd_data_pad_oe_o ? ps2_kbd_data_pad_o : 1'bz ;
+
+`ifdef PS2_AUX
+assign ps2_aux_clk_io = ps2_aux_clk_pad_oe_o ? ps2_aux_clk_pad_o : 1'bz ;
+assign ps2_aux_data_io = ps2_aux_data_pad_oe_o ? ps2_aux_data_pad_o : 1'bz ;
+`endif
+endmodule
Index: tags/rel_13/bench/verilog/ps2_testbench_defines.v
===================================================================
--- tags/rel_13/bench/verilog/ps2_testbench_defines.v (nonexistent)
+++ tags/rel_13/bench/verilog/ps2_testbench_defines.v (revision 42)
@@ -0,0 +1,153 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_testbench_defines.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.2 2002/04/09 13:17:38 mihad
+// Mouse interface testcases added
+//
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+//===================================================================================
+// User-unchangeable testbench defines (constants)
+//===================================================================================
+
+// setup and hold time definitions for WISHBONE - used in BFMs for signal generation
+`define Tsetup 2
+`define Thold 2
+
+// how many clock cycles should model wait for design's response - integer 32 bit value
+`define WAIT_FOR_RESPONSE 6
+
+// maximum number of transactions allowed in single call to block or cab transfer routines
+`define MAX_BLK_SIZE 8
+
+// maximum retry terminations allows for WISHBONE master to repeat an access
+`define WB_TB_MAX_RTY 1000
+
+
+// some common types and defines
+`define WB_ADDR_WIDTH 32
+`define WB_DATA_WIDTH 32
+`define WB_SEL_WIDTH `WB_DATA_WIDTH/8
+`define WB_TAG_WIDTH 1
+`define WB_ADDR_TYPE [(`WB_ADDR_WIDTH - 1):0]
+`define WB_DATA_TYPE [(`WB_DATA_WIDTH - 1):0]
+`define WB_SEL_TYPE [(`WB_SEL_WIDTH - 1):0]
+`define WB_TAG_TYPE [(`WB_TAG_WIDTH - 1):0]
+
+// definitions file only for testbench usage
+// wishbone master behavioral defines
+// flags type for wishbone cycle initialization
+`define CYC_FLAG_TYPE [0:0]
+// cab flag field in cycle initialization data
+`define CYC_CAB_FLAG [0]
+// read cycle stimulus - consists of:
+// - address field - which address read will be performed from
+// - sel field - what byte select value should be
+// - tag field - what tag values should be put on the bus
+`define READ_STIM_TYPE [(`WB_ADDR_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH - 1):0]
+`define READ_STIM_LENGTH (`WB_ADDR_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH)
+`define READ_ADDRESS [(`WB_ADDR_WIDTH - 1):0]
+`define READ_SEL [(`WB_ADDR_WIDTH + `WB_SEL_WIDTH - 1):`WB_ADDR_WIDTH]
+`define READ_TAG_STIM [(`WB_ADDR_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH - 1):(`WB_ADDR_WIDTH + `WB_SEL_WIDTH)]
+
+// read cycle return type consists of:
+// - read data field
+// - tag field received from WISHBONE
+// - wishbone slave response fields - ACK, ERR and RTY
+// - test bench error indicator (when testcase has not used wb master model properly)
+// - how much data was actually transfered
+`define READ_RETURN_TYPE [(32 + 4 + `WB_DATA_WIDTH + `WB_TAG_WIDTH - 1):0]
+`define READ_DATA [(32 + `WB_DATA_WIDTH + 4 - 1):32 + 4]
+`define READ_TAG_RET [(32 + 4 + `WB_DATA_WIDTH + `WB_TAG_WIDTH - 1):(`WB_DATA_WIDTH + 32 + 4)]
+`define READ_RETURN_LENGTH (32 + 4 + `WB_DATA_WIDTH + `WB_TAG_WIDTH - 1)
+
+// write cycle stimulus type consists of
+// - address field
+// - data field
+// - sel field
+// - tag field
+`define WRITE_STIM_TYPE [(`WB_ADDR_WIDTH + `WB_DATA_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH - 1):0]
+`define WRITE_ADDRESS [(`WB_ADDR_WIDTH - 1):0]
+`define WRITE_DATA [(`WB_ADDR_WIDTH + `WB_DATA_WIDTH - 1):`WB_ADDR_WIDTH]
+`define WRITE_SEL [(`WB_ADDR_WIDTH + `WB_DATA_WIDTH + `WB_SEL_WIDTH - 1):(`WB_ADDR_WIDTH + `WB_DATA_WIDTH)]
+`define WRITE_TAG_STIM [(`WB_ADDR_WIDTH + `WB_DATA_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH - 1):(`WB_ADDR_WIDTH + `WB_DATA_WIDTH + `WB_SEL_WIDTH)]
+
+// length of WRITE_STIMULUS
+`define WRITE_STIM_LENGTH (`WB_ADDR_WIDTH + `WB_DATA_WIDTH + `WB_SEL_WIDTH + `WB_TAG_WIDTH)
+
+// write cycle return type consists of:
+// - test bench error indicator (when testcase has not used wb master model properly)
+// - wishbone slave response fields - ACK, ERR and RTY
+// - tag field received from WISHBONE
+// - how much data was actually transfered
+`define WRITE_RETURN_TYPE [(32 + 4 + `WB_TAG_WIDTH - 1):0]
+`define WRITE_TAG_RET [(32 + 4 + `WB_TAG_WIDTH - 1):32 + 4]
+
+// this four fields are common to both read and write routines return values
+`define TB_ERROR_BIT [0]
+`define CYC_ACK [1]
+`define CYC_RTY [2]
+`define CYC_ERR [3]
+`define CYC_RESPONSE [3:1]
+`define CYC_ACTUAL_TRANSFER [35:4]
+
+// block transfer flags
+`define WB_TRANSFER_FLAGS [41:0]
+// consists of:
+// - number of transfer cycles to perform
+// - flag that enables retry termination handling - if disabled, block transfer routines will return on any termination other than acknowledge
+// - flag indicating CAB transfer is to be performed - ignored by all single transfer routines
+// - number of initial wait states to insert
+// - number of subsequent wait states to insert
+`define WB_TRANSFER_SIZE [41:10]
+`define WB_TRANSFER_AUTO_RTY [8]
+`define WB_TRANSFER_CAB [9]
+`define INIT_WAITS [3:0]
+`define SUBSEQ_WAITS [7:4]
+
+`define WB_FREQ 0.10
Index: tags/rel_13/bench/verilog/ps2_keyboard_model.v
===================================================================
--- tags/rel_13/bench/verilog/ps2_keyboard_model.v (nonexistent)
+++ tags/rel_13/bench/verilog/ps2_keyboard_model.v (revision 42)
@@ -0,0 +1,296 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_keyboard_model.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.2 2002/04/09 13:15:16 mihad
+// Wrong acknowledge generation during receiving repaired
+//
+// Revision 1.1.1.1 2002/02/18 16:16:55 mihad
+// Initial project import - working
+//
+//
+
+`include "timescale.v"
+
+module ps2_keyboard_model
+(
+ kbd_clk_io,
+ kbd_data_io,
+ last_char_received_o,
+ char_valid_o
+);
+
+parameter [31:0] kbd_clk_period = 50000; // chould be between 33 and 50 us to generate the clock between 30 and 20 kHz
+
+inout kbd_clk_io,
+ kbd_data_io ;
+
+output [7:0] last_char_received_o ;
+reg [7:0] last_char_received_o ;
+
+output char_valid_o ;
+reg char_valid_o ;
+
+reg kbd_clk,
+ kbd_data ;
+
+assign kbd_clk_io = kbd_clk ? 1'bz : 1'b0 ;
+assign kbd_data_io = kbd_data ? 1'bz : 1'b0 ;
+
+reg receiving ;
+initial
+begin
+ kbd_clk = 1'b1 ;
+ kbd_data = 1'b1 ;
+
+ last_char_received_o = 0 ;
+ char_valid_o = 0 ;
+
+ receiving = 0 ;
+end
+
+always@(kbd_data_io or kbd_clk_io)
+begin
+ // check if host is driving keyboard data low and doesn't drive clock
+ if ( !kbd_data_io && kbd_data && kbd_clk_io)
+ begin
+ // wait for half of clock period
+ #(kbd_clk_period/2) ;
+
+ // state hasn't changed - host wishes to send data - go receiving
+ if ( !kbd_data_io && kbd_data && kbd_clk_io)
+ kbd_receive_char(last_char_received_o) ;
+ end
+end
+
+task kbd_send_char ;
+ input [7:0] char ;
+ output transmited_ok ;
+ output severe_error ;
+ reg [10:0] tx_reg ;
+ integer i ;
+begin:main
+ severe_error = 1'b0 ;
+ transmited_ok = 1'b0 ;
+
+ wait ( !receiving ) ;
+
+ tx_reg = { 1'b1, !(^char), char, 1'b0 } ;
+
+ fork
+ begin:wait_for_idle
+ wait( (kbd_clk_io === 1'b1) && (kbd_data_io === 1'b1) ) ;
+ // disable timeout ;
+ end
+ /*begin:timeout
+ #(256 * kbd_clk_period) ;
+ $display("Error! Keyboard bus did not go idle in 256 keyboard clock cycles time!") ;
+ severe_error = 1'b1 ;
+ transmited_ok = 1'b0 ;
+ disable main ;
+ end*/
+ join
+
+ #(kbd_clk_period/2) ;
+ if ( !kbd_clk_io )
+ begin
+ transmited_ok = 1'b0 ;
+ kbd_data = 1'b1 ;
+ disable main ;
+ end
+
+ i = 0 ;
+ while ( i < 11 )
+ begin
+ kbd_data = tx_reg[i] ;
+
+ #(kbd_clk_period/2) ;
+
+ if ( !kbd_clk_io )
+ begin
+ transmited_ok = 1'b0 ;
+ kbd_data = 1'b1 ;
+ disable main ;
+ end
+
+ kbd_clk = 1'b0 ;
+
+ i = i + 1 ;
+
+ #(kbd_clk_period/2) ;
+ kbd_clk = 1'b1 ;
+ end
+
+ if ( i == 11 )
+ transmited_ok = 1'b1 ;
+end
+endtask // kbd_send_char
+
+task kbd_receive_char;
+ output [7:0] char ;
+ reg parity ;
+ integer i ;
+ reg stop_clocking ;
+begin:main
+ i = 0 ;
+ receiving = 1 ;
+ stop_clocking = 1'b0 ;
+
+ #(kbd_clk_period/2) ;
+
+ while ( !stop_clocking )
+ begin
+
+ if ( !kbd_clk_io )
+ begin
+ receiving = 0 ;
+ disable main ;
+ end
+
+ kbd_clk = 1'b0 ;
+
+ #(kbd_clk_period/2) ;
+
+ kbd_clk = 1'b1 ;
+
+ if ( i > 0 )
+ begin
+ if ( i <= 8 )
+ char[i - 1] = kbd_data_io ;
+ else if ( i == 9 )
+ begin
+ parity = kbd_data_io ;
+ if ( parity !== ( !(^char) ) )
+ $display("Invalid parity bit received") ;
+ end
+ end
+
+ i = i + 1 ;
+ #(kbd_clk_period/4) ;
+ if ( i > 9 )
+ begin
+ if ( kbd_data_io === 1'b1 )
+ begin
+ kbd_data <= 1'b0 ;
+ stop_clocking = 1'b1 ;
+ end
+ end
+
+ #(kbd_clk_period/4) ;
+ end
+
+ kbd_clk = 1'b0 ;
+
+ #(kbd_clk_period/2) ;
+ kbd_clk <= 1'b1 ;
+ kbd_data <= 1'b1 ;
+
+ receiving = 0 ;
+
+ if ( i === 10 )
+ begin
+ char_valid_o = !char_valid_o ;
+ end
+end
+endtask // kbd_receive_char
+
+
+time last_clk_low;
+time last_clk_diference;
+
+
+
+initial
+begin
+last_clk_low =0;
+last_clk_diference =0;
+
+end
+
+always @(negedge kbd_clk_io)
+
+ begin:low_time_check
+ if (kbd_clk == 1)
+ begin
+ last_clk_low =$time;
+ fork
+ begin
+ #61000
+ $display(" clock low more then 61us");
+ $display("Time %t", $time) ;
+ #30000
+ $display("error clock low more then 90usec");
+ $display("Time %t", $time) ;
+ $stop;
+ end
+ begin
+ @(posedge kbd_clk_io);
+ disable low_time_check;
+ end
+ join
+ end
+ end
+
+
+
+
+always @(posedge kbd_clk_io )
+ begin
+ if (last_clk_low >0 )
+ begin
+ last_clk_diference = $time - last_clk_low;
+ if (last_clk_diference < 60000)
+ begin
+ $display("error time< 60u");
+ #100 $stop;
+ end
+ end
+ end
+
+
+
+
+
+
+endmodule // ps2_keyboard_model
Index: tags/rel_13/bench/verilog/wb_master_behavioral.v
===================================================================
--- tags/rel_13/bench/verilog/wb_master_behavioral.v (nonexistent)
+++ tags/rel_13/bench/verilog/wb_master_behavioral.v (revision 42)
@@ -0,0 +1,773 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// wb_master_behavioral.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+//
+
+`include "ps2_testbench_defines.v"
+`include "timescale.v"
+module WB_MASTER_BEHAVIORAL
+(
+ CLK_I,
+ RST_I,
+ TAG_I,
+ TAG_O,
+ ACK_I,
+ ADR_O,
+ CYC_O,
+ DAT_I,
+ DAT_O,
+ ERR_I,
+ RTY_I,
+ SEL_O,
+ STB_O,
+ WE_O,
+ CAB_O
+);
+
+ input CLK_I;
+ input RST_I;
+ input `WB_TAG_TYPE TAG_I;
+ output `WB_TAG_TYPE TAG_O;
+ input ACK_I;
+ output `WB_ADDR_TYPE ADR_O;
+ output CYC_O;
+ input `WB_DATA_TYPE DAT_I;
+ output `WB_DATA_TYPE DAT_O;
+ input ERR_I;
+ input RTY_I;
+ output `WB_SEL_TYPE SEL_O;
+ output STB_O;
+ output WE_O;
+ output CAB_O;
+
+// instantiate low level master module
+WB_MASTER32 wbm_low_level
+(
+ .CLK_I(CLK_I),
+ .RST_I(RST_I),
+ .TAG_I(TAG_I),
+ .TAG_O(TAG_O),
+ .ACK_I(ACK_I),
+ .ADR_O(ADR_O),
+ .CYC_O(CYC_O),
+ .DAT_I(DAT_I),
+ .DAT_O(DAT_O),
+ .ERR_I(ERR_I),
+ .RTY_I(RTY_I),
+ .SEL_O(SEL_O),
+ .STB_O(STB_O),
+ .WE_O(WE_O),
+ .CAB_O(CAB_O)
+) ;
+
+// block read and write buffers definition
+// single write buffer
+reg `WRITE_STIM_TYPE blk_write_data [0:(`MAX_BLK_SIZE - 1)] ;
+// read stimulus buffer - addresses, tags, selects etc.
+reg `READ_STIM_TYPE blk_read_data_in [0:(`MAX_BLK_SIZE - 1)] ;
+// read return buffer - data and tags received while performing block reads
+reg `READ_RETURN_TYPE blk_read_data_out [0:(`MAX_BLK_SIZE - 1)] ;
+
+// single write task
+task wb_single_write ;
+ input `WRITE_STIM_TYPE write_data ;
+ input `WB_TRANSFER_FLAGS write_flags ;
+ inout `WRITE_RETURN_TYPE return ;
+ reg in_use ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg retry ;
+begin:main
+
+ return`TB_ERROR_BIT = 1'b0 ;
+ cab = 0 ;
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+ rty_count = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_single_write routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+
+ retry = 1 ;
+
+ while (retry === 1)
+ begin
+ // synchronize operation to clock
+ @(posedge CLK_I) ;
+
+ wbm_low_level.start_cycle(cab, 1'b1, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_single_write, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // first insert initial wait states
+ cyc_count = write_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.wbm_write(write_data, return) ;
+
+ if ( return`CYC_ERR === 0 && return`CYC_ACK === 0 && return`CYC_RTY === 1 && write_flags`WB_TRANSFER_AUTO_RTY === 1 && return`TB_ERROR_BIT === 0)
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_single_write, Time %t ", $time) ;
+ retry = 0 ;
+ end
+ else
+ begin
+ retry = 1 ;
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ retry = 0 ;
+
+ // if test bench error bit is set, there is no meaning in introducing subsequent wait states
+ if ( return`TB_ERROR_BIT !== 0 )
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ cyc_count = write_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.end_cycle ;
+ end
+
+ in_use = 0 ;
+
+end //main
+endtask // wb_single_write
+
+task wb_single_read ;
+ input `READ_STIM_TYPE read_data ;
+ input `WB_TRANSFER_FLAGS read_flags ;
+ inout `READ_RETURN_TYPE return ;
+ reg in_use ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg retry ;
+begin:main
+
+ return`TB_ERROR_BIT = 1'b0 ;
+ cab = 0 ;
+ rty_count = 0 ;
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_single_read routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+
+ retry = 1 ;
+
+ while (retry === 1)
+ begin
+ // synchronize operation to clock
+ @(posedge CLK_I) ;
+
+ wbm_low_level.start_cycle(cab, 1'b0, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_single_read, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // first insert initial wait states
+ cyc_count = read_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.wbm_read(read_data, return) ;
+
+ if ( return`CYC_ERR === 0 && return`CYC_ACK === 0 && return`CYC_RTY === 1 && read_flags`WB_TRANSFER_AUTO_RTY === 1 && return`TB_ERROR_BIT === 0)
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_single_read, Time %t ", $time) ;
+ retry = 0 ;
+ end
+ else
+ begin
+ retry = 1 ;
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ begin
+ retry = 0 ;
+ end
+
+ // if test bench error bit is set, there is no meaning in introducing subsequent wait states
+ if ( return`TB_ERROR_BIT !== 0 )
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ cyc_count = read_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.end_cycle ;
+ end
+
+ in_use = 0 ;
+
+end //main
+endtask // wb_single_read
+
+task wb_RMW_read ;
+ input `READ_STIM_TYPE read_data ;
+ input `WB_TRANSFER_FLAGS read_flags ;
+ inout `READ_RETURN_TYPE return ;
+ reg in_use ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg retry ;
+begin:main
+
+ return`TB_ERROR_BIT = 1'b0 ;
+ cab = 0 ;
+ rty_count = 0 ;
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_RMW_read routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+
+ retry = 1 ;
+
+ while (retry === 1)
+ begin
+ // synchronize operation to clock
+ @(posedge CLK_I) ;
+
+ wbm_low_level.start_cycle(cab, 1'b0, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_RMW_read, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // first insert initial wait states
+ cyc_count = read_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.wbm_read(read_data, return) ;
+
+ if ( return`CYC_ERR === 0 && return`CYC_ACK === 0 && return`CYC_RTY === 1 && read_flags`WB_TRANSFER_AUTO_RTY === 1 && return`TB_ERROR_BIT === 0)
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_RMW_read, Time %t ", $time) ;
+ retry = 0 ;
+ end
+ else
+ begin
+ retry = 1 ;
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ begin
+ retry = 0 ;
+ end
+
+ // if test bench error bit is set, there is no meaning in introducing subsequent wait states
+ if ( return`TB_ERROR_BIT !== 0 )
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ cyc_count = read_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ if (retry === 1)
+ wbm_low_level.end_cycle ;
+ else
+ wbm_low_level.modify_cycle ;
+ end
+
+ in_use = 0 ;
+
+end //main
+endtask // wb_RMW_read
+
+task wb_RMW_write ;
+ input `WRITE_STIM_TYPE write_data ;
+ input `WB_TRANSFER_FLAGS write_flags ;
+ inout `WRITE_RETURN_TYPE return ;
+ reg in_use ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg retry ;
+begin:main
+
+ return`TB_ERROR_BIT = 1'b0 ;
+ cab = 0 ;
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+ rty_count = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_RMW_write routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+
+ retry = 1 ;
+
+ while (retry === 1)
+ begin
+ // synchronize operation to clock
+ @(posedge CLK_I) ;
+ ok = 1 ;
+ if (rty_count !== 0)
+ wbm_low_level.start_cycle(cab, 1'b1, ok) ;
+
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_single_write, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // first insert initial wait states
+ cyc_count = write_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.wbm_write(write_data, return) ;
+
+ if ( return`CYC_ERR === 0 && return`CYC_ACK === 0 && return`CYC_RTY === 1 && write_flags`WB_TRANSFER_AUTO_RTY === 1 && return`TB_ERROR_BIT === 0)
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_single_write, Time %t ", $time) ;
+ retry = 0 ;
+ end
+ else
+ begin
+ retry = 1 ;
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ retry = 0 ;
+
+ // if test bench error bit is set, there is no meaning in introducing subsequent wait states
+ if ( return`TB_ERROR_BIT !== 0 )
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ cyc_count = write_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ wbm_low_level.end_cycle ;
+ end
+
+ in_use = 0 ;
+
+end //main
+endtask // wb_RMW_write
+
+task wb_block_write ;
+ input `WB_TRANSFER_FLAGS write_flags ;
+ inout `WRITE_RETURN_TYPE return ;
+
+ reg in_use ;
+ reg `WRITE_STIM_TYPE current_write ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg end_blk ;
+begin:main
+
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+ rty_count = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_block_write routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if (write_flags`WB_TRANSFER_SIZE > `MAX_BLK_SIZE)
+ begin
+ $display("*E, number of transfers passed to wb_block_write routine exceeds defined maximum transaction length! Time %t", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+ @(posedge CLK_I) ;
+ cab = write_flags`WB_TRANSFER_CAB ;
+ wbm_low_level.start_cycle(cab, 1'b1, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_block_write, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // insert initial wait states
+ cyc_count = write_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ end_blk = 0 ;
+ while (end_blk === 0)
+ begin
+ // collect data for current data beat
+ current_write = blk_write_data[return`CYC_ACTUAL_TRANSFER] ;
+ wbm_low_level.wbm_write(current_write, return) ;
+
+ // check result of write operation
+ // check for severe test error
+ if (return`TB_ERROR_BIT !== 0)
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ // slave returned error or error signal had invalid value
+ if (return`CYC_ERR !== 0)
+ end_blk = 1 ;
+
+ if (
+ (return`CYC_RTY !== 0) && (return`CYC_RTY !== 1) ||
+ (return`CYC_ACK !== 0) && (return`CYC_ACK !== 1) ||
+ (return`CYC_ERR !== 0) && (return`CYC_ERR !== 1)
+ )
+ begin
+ end_blk = 1 ;
+ $display("*E, at least one slave response signal was invalid when cycle finished! Routine wb_block_write, Time %t ", $time) ;
+ $display("ACK = %b \t RTY_O = %b \t ERR_O = %b \t", return`CYC_ACK, return`CYC_RTY, return`CYC_ERR) ;
+ end
+
+ if ((return`CYC_RTY === 1) && (write_flags`WB_TRANSFER_AUTO_RTY !== 1))
+ end_blk = 1 ;
+
+ if ((return`CYC_RTY === 1) && (write_flags`WB_TRANSFER_AUTO_RTY === 1))
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_block_write, Time %t ", $time) ;
+ end_blk = 1 ;
+ end
+ else
+ begin
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ rty_count = 0 ;
+
+ // check if slave responded at all
+ if (return`CYC_RESPONSE === 0)
+ end_blk = 1 ;
+
+ // check if all intended data was transfered
+ if (return`CYC_ACTUAL_TRANSFER === write_flags`WB_TRANSFER_SIZE)
+ end_blk = 1 ;
+
+ // insert subsequent wait cycles, if transfer is supposed to continue
+ if ( end_blk === 0 )
+ begin
+ cyc_count = write_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+ end
+
+ if ( (end_blk === 0) && (return`CYC_RTY === 1) )
+ begin
+ wbm_low_level.end_cycle ;
+ @(posedge CLK_I) ;
+ wbm_low_level.start_cycle(cab, 1'b1, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_block_write, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ end_blk = 1 ;
+ end
+ end
+ end //while
+
+ wbm_low_level.end_cycle ;
+ in_use = 0 ;
+end //main
+endtask //wb_block_write
+
+task wb_block_read ;
+ input `WB_TRANSFER_FLAGS read_flags ;
+ inout `READ_RETURN_TYPE return ;
+
+ reg in_use ;
+ reg `READ_STIM_TYPE current_read ;
+ reg cab ;
+ reg ok ;
+ integer cyc_count ;
+ integer rty_count ;
+ reg end_blk ;
+ integer transfered ;
+begin:main
+
+ return`CYC_ACTUAL_TRANSFER = 0 ;
+ transfered = 0 ;
+ rty_count = 0 ;
+
+ // check if task was called before previous call finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wb_block_read routine re-entered! Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if (read_flags`WB_TRANSFER_SIZE > `MAX_BLK_SIZE)
+ begin
+ $display("*E, number of transfers passed to wb_block_read routine exceeds defined maximum transaction length! Time %t", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ in_use = 1 ;
+ @(posedge CLK_I) ;
+ cab = read_flags`WB_TRANSFER_CAB ;
+
+ wbm_low_level.start_cycle(cab, 1'b0, ok) ;
+
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_block_read, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // insert initial wait states
+ cyc_count = read_flags`INIT_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+
+ end_blk = 0 ;
+ while (end_blk === 0)
+ begin
+ // collect data for current data beat
+ current_read = blk_read_data_in[return`CYC_ACTUAL_TRANSFER] ;
+
+ wbm_low_level.wbm_read(current_read, return) ;
+
+ if ( transfered !== return`CYC_ACTUAL_TRANSFER )
+ begin
+ blk_read_data_out[transfered] = return ;
+ transfered = return`CYC_ACTUAL_TRANSFER ;
+ end
+
+ // check result of read operation
+ // check for severe test error
+ if (return`TB_ERROR_BIT !== 0)
+ begin
+ @(posedge CLK_I) ;
+ wbm_low_level.end_cycle ;
+ disable main ;
+ end
+
+ // slave returned error or error signal had invalid value
+ if (return`CYC_ERR !== 0)
+ end_blk = 1 ;
+
+ if (
+ (return`CYC_RTY !== 0) && (return`CYC_RTY !== 1) ||
+ (return`CYC_ACK !== 0) && (return`CYC_ACK !== 1) ||
+ (return`CYC_ERR !== 0) && (return`CYC_ERR !== 1)
+ )
+ begin
+ end_blk = 1 ;
+ $display("*E, at least one slave response signal was invalid when cycle finished! Routine wb_block_read, Time %t ", $time) ;
+ $display("ACK = %b \t RTY_O = %b \t ERR_O = %b \t", return`CYC_ACK, return`CYC_RTY, return`CYC_ERR) ;
+ end
+
+ if ((return`CYC_RTY === 1) && (read_flags`WB_TRANSFER_AUTO_RTY !== 1))
+ end_blk = 1 ;
+
+ if ((return`CYC_RTY === 1) && (read_flags`WB_TRANSFER_AUTO_RTY === 1))
+ begin
+ if ( rty_count === `WB_TB_MAX_RTY )
+ begin
+ $display("*E, maximum number of retries received - access will not be repeated anymore! Routine wb_block_read, Time %t ", $time) ;
+ end_blk = 1 ;
+ end
+ else
+ begin
+ rty_count = rty_count + 1 ;
+ end
+ end
+ else
+ rty_count = 0 ;
+
+ // check if slave responded at all
+ if (return`CYC_RESPONSE === 0)
+ end_blk = 1 ;
+
+ // check if all intended data was transfered
+ if (return`CYC_ACTUAL_TRANSFER === read_flags`WB_TRANSFER_SIZE)
+ end_blk = 1 ;
+
+ // insert subsequent wait cycles, if transfer is supposed to continue
+ if ( end_blk === 0 )
+ begin
+ cyc_count = read_flags`SUBSEQ_WAITS ;
+ while ( cyc_count > 0 )
+ begin
+ @(posedge CLK_I) ;
+ cyc_count = cyc_count - 1 ;
+ end
+ end
+
+ if ( (end_blk === 0) && (return`CYC_RTY === 1) )
+ begin
+ wbm_low_level.end_cycle ;
+ @(posedge CLK_I) ;
+ wbm_low_level.start_cycle(cab, 1'b0, ok) ;
+ if ( ok !== 1 )
+ begin
+ $display("*E, Failed to initialize cycle! Routine wb_block_read, Time %t ", $time) ;
+ return`TB_ERROR_BIT = 1'b1 ;
+ end_blk = 1 ;
+ end
+ end
+ end //while
+
+ wbm_low_level.end_cycle ;
+ in_use = 0 ;
+end //main
+endtask //wb_block_read
+
+endmodule
+
Index: tags/rel_13/bench/verilog/wb_master32.v
===================================================================
--- tags/rel_13/bench/verilog/wb_master32.v (nonexistent)
+++ tags/rel_13/bench/verilog/wb_master32.v (revision 42)
@@ -0,0 +1,366 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// wb_master32.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+//
+
+`include "ps2_testbench_defines.v"
+`include "timescale.v"
+module WB_MASTER32
+(
+ CLK_I,
+ RST_I,
+ TAG_I,
+ TAG_O,
+ ACK_I,
+ ADR_O,
+ CYC_O,
+ DAT_I,
+ DAT_O,
+ ERR_I,
+ RTY_I,
+ SEL_O,
+ STB_O,
+ WE_O,
+ CAB_O
+);
+
+ input CLK_I;
+ input RST_I;
+ input `WB_TAG_TYPE TAG_I;
+ output `WB_TAG_TYPE TAG_O;
+ input ACK_I;
+ output `WB_ADDR_TYPE ADR_O;
+ output CYC_O;
+ input `WB_DATA_TYPE DAT_I;
+ output `WB_DATA_TYPE DAT_O;
+ input ERR_I;
+ input RTY_I;
+ output `WB_SEL_TYPE SEL_O;
+ output STB_O;
+ output WE_O;
+ output CAB_O ;
+
+ // period length
+ real Tp ;
+
+ reg `WB_ADDR_TYPE ADR_O;
+ reg `WB_SEL_TYPE SEL_O;
+ reg `WB_TAG_TYPE TAG_O;
+ reg CYC_O;
+ reg WE_O;
+ reg `WB_DATA_TYPE DAT_O;
+ reg CAB_O ;
+ reg STB_O ;
+
+ // variable used for indication on whether cycle was already started
+ reg in_use ;
+
+ // because of non-blocking assignments CYC_O is not sufficient indicator for cycle starting - this var is used in its place
+ reg cycle_in_progress ;
+
+ // same goes for CAB_O signal
+ reg cab ;
+
+ reg we ;
+
+ task start_cycle ;
+ input is_cab ;
+ input write ;
+ output ok ; // ok indicates to the caller that cycle was started succesfully - if not, caller must take appropriate action
+ begin:main
+
+ ok = 1 ;
+
+ // just check if valid value is provided for CAB_O signal (no x's or z's allowed)
+ if ( (is_cab !== 1'b0) && (is_cab !== 1'b1) )
+ begin
+ $display("*E, invalid CAB value for cycle! Requested CAB_O value = %b, Time %t ", is_cab, $time) ;
+ ok = 0 ;
+ disable main ;
+ end
+
+ if ( (cycle_in_progress === 1) || (CYC_O === 1))
+ begin
+ // cycle was previously started - allow cycle to continue if CAB and WE values match
+ $display("*W, cycle already in progress when start_cycle routine was called! Time %t ", $time) ;
+ if ((CAB_O !== is_cab) || (WE_O !== write) )
+ begin
+ ok = 0 ;
+ if ( is_cab === 1 )
+ $display("*E, cab cycle start attempted when non-cab cycle was in progress! Time %t", $time) ;
+ else
+ $display("*E, non-cab cycle start attempted when cab cycle was in progress! Time %t", $time) ;
+
+ if ( we === 1 )
+ $display("*E, write cycle start attempted when read cycle was in progress! Time %t", $time) ;
+ else
+ $display("*E, read cycle start attempted when write cycle was in progress! Time %t", $time) ;
+
+ disable main ;
+ end
+ end
+
+ CYC_O <= #(Tp - `Tsetup) 1'b1 ;
+ CAB_O <= #(Tp - `Tsetup) is_cab ;
+ WE_O <= #(Tp - `Tsetup) write ;
+
+ // this non-blocking assignments are made to internal variables, so read and write tasks can be called immediately after cycle start task
+ cycle_in_progress = 1'b1 ;
+ cab = is_cab ;
+ we = write ;
+ end
+ endtask //start_cycle
+
+ task end_cycle ;
+ begin
+ if ( CYC_O !== 1'b1 )
+ $display("*W, end_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
+
+ CYC_O <= #`Thold 1'b0 ;
+ CAB_O <= #`Thold 1'b0 ;
+ cycle_in_progress = 1'b0 ;
+ end
+ endtask //end_cycle
+
+ task modify_cycle ;
+ begin
+ if ( CYC_O !== 1'b1 )
+ $display("*W, modify_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
+
+ we = ~we ;
+ WE_O <= #(Tp - `Tsetup) we ;
+ end
+ endtask //modify_cycle
+
+ task wbm_read ;
+ input `READ_STIM_TYPE input_data ;
+ inout `READ_RETURN_TYPE output_data ;
+ reg `WB_ADDR_TYPE address ;
+ reg `WB_DATA_TYPE data ;
+ reg `WB_SEL_TYPE sel ;
+ reg `WB_TAG_TYPE tag ;
+ integer num_of_cyc ;
+ begin:main
+ output_data`TB_ERROR_BIT = 1'b0 ;
+
+ // check if task was called before previous call to read or write finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wbm_read routine re-entered or called concurently with write routine! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if ( cycle_in_progress !== 1 )
+ begin
+ $display("*E, wbm_read routine called without start_cycle routine being called first! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if ( we !== 0 )
+ begin
+ $display("*E, wbm_read routine called after write cycle was started! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // this branch contains timing controls - claim the use of WISHBONE
+ in_use = 1 ;
+
+ num_of_cyc = `WAIT_FOR_RESPONSE ;
+
+ // assign data outputs
+ ADR_O <= #(Tp - `Tsetup) input_data`READ_ADDRESS ;
+ SEL_O <= #(Tp - `Tsetup) input_data`READ_SEL ;
+ TAG_O <= #(Tp - `Tsetup) input_data`READ_TAG_STIM ;
+
+ // assign control output
+ STB_O <= #(Tp - `Tsetup) 1'b1 ;
+
+ output_data`CYC_ACK = 0 ;
+ output_data`CYC_RTY = 0 ;
+ output_data`CYC_ERR = 0 ;
+
+ @(posedge CLK_I) ;
+ output_data`CYC_ACK = ACK_I ;
+ output_data`CYC_RTY = RTY_I ;
+ output_data`CYC_ERR = ERR_I ;
+
+ while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
+ begin
+ @(posedge CLK_I) ;
+ output_data`CYC_ACK = ACK_I ;
+ output_data`CYC_RTY = RTY_I ;
+ output_data`CYC_ERR = ERR_I ;
+ num_of_cyc = num_of_cyc - 1 ;
+ end
+
+ output_data`READ_DATA = DAT_I ;
+ output_data`READ_TAG_RET = TAG_I ;
+
+ if ( output_data`CYC_RESPONSE === 0 )
+ begin
+
+ $display("*W, Terminating read cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
+ end
+
+ if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
+ output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
+
+ STB_O <= #`Thold 1'b0 ;
+ ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
+ SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
+ TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
+
+ in_use = 0 ;
+ end
+ endtask // wbm_read
+
+ task wbm_write ;
+ input `WRITE_STIM_TYPE input_data ;
+ inout `WRITE_RETURN_TYPE output_data ;
+ reg `WB_ADDR_TYPE address ;
+ reg `WB_DATA_TYPE data ;
+ reg `WB_SEL_TYPE sel ;
+ reg `WB_TAG_TYPE tag ;
+ integer num_of_cyc ;
+ begin:main
+ output_data`TB_ERROR_BIT = 1'b0 ;
+
+ // check if task was called before previous call to read or write finished
+ if ( in_use === 1 )
+ begin
+ $display("*E, wbm_write routine re-entered or called concurently with read routine! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if ( cycle_in_progress !== 1 )
+ begin
+ $display("*E, wbm_write routine called without start_cycle routine being called first! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ if ( we !== 1 )
+ begin
+ $display("*E, wbm_write routine after read cycle was started! Time %t ", $time) ;
+ output_data`TB_ERROR_BIT = 1'b1 ;
+ disable main ;
+ end
+
+ // this branch contains timing controls - claim the use of WISHBONE
+ in_use = 1 ;
+
+ num_of_cyc = `WAIT_FOR_RESPONSE ;
+
+ ADR_O <= #(Tp - `Tsetup) input_data`WRITE_ADDRESS ;
+ DAT_O <= #(Tp - `Tsetup) input_data`WRITE_DATA ;
+ SEL_O <= #(Tp - `Tsetup) input_data`WRITE_SEL ;
+ TAG_O <= #(Tp - `Tsetup) input_data`WRITE_TAG_STIM ;
+
+ STB_O <= #(Tp - `Tsetup) 1'b1 ;
+
+ output_data`CYC_ACK = 0 ;
+ output_data`CYC_RTY = 0 ;
+ output_data`CYC_ERR = 0 ;
+
+ @(posedge CLK_I) ;
+ output_data`CYC_ACK = ACK_I ;
+ output_data`CYC_RTY = RTY_I ;
+ output_data`CYC_ERR = ERR_I ;
+
+ while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
+ begin
+ @(posedge CLK_I) ;
+ output_data`CYC_ACK = ACK_I ;
+ output_data`CYC_RTY = RTY_I ;
+ output_data`CYC_ERR = ERR_I ;
+ num_of_cyc = num_of_cyc - 1 ;
+ end
+
+ output_data`WRITE_TAG_RET = TAG_I ;
+ if ( output_data`CYC_RESPONSE === 0 )
+ begin
+ $display("*W, Terminating write cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
+ end
+
+ if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
+ output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
+
+ ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
+ DAT_O <= #`Thold {`WB_DATA_WIDTH{1'bx}} ;
+ SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
+ TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
+
+ STB_O <= #`Thold 1'b0 ;
+
+ in_use = 0 ;
+ end
+ endtask //wbm_write
+
+ initial
+ begin
+ Tp = 1 / `WB_FREQ ;
+ in_use = 0 ;
+ cycle_in_progress = 0 ;
+ cab = 0 ;
+ ADR_O <= {`WB_ADDR_WIDTH{1'bx}} ;
+ DAT_O <= {`WB_DATA_WIDTH{1'bx}} ;
+ SEL_O <= {`WB_SEL_WIDTH{1'bx}} ;
+ TAG_O <= {`WB_TAG_WIDTH{1'bx}} ;
+ CYC_O <= 1'b0 ;
+ STB_O <= 1'b0 ;
+ CAB_O <= 1'b0 ;
+ WE_O <= 1'b0 ;
+ if ( `Tsetup > Tp || `Thold >= Tp )
+ begin
+ $display("Either Tsetup or Thold values for WISHBONE BFMs are too large!") ;
+ $stop ;
+ end
+ end
+
+endmodule
Index: tags/rel_13/bench/data/extended_scancodes_set1.hex
===================================================================
--- tags/rel_13/bench/data/extended_scancodes_set1.hex (nonexistent)
+++ tags/rel_13/bench/data/extended_scancodes_set1.hex (revision 42)
@@ -0,0 +1,38 @@
+5B
+1D
+5C
+38
+5D
+52
+47
+49
+53
+4F
+51
+48
+4B
+50
+4D
+35
+1C
+5E
+5F
+63
+19
+10
+24
+22
+20
+30
+2E
+6D
+6C
+21
+6B
+65
+32
+6A
+69
+68
+67
+66
\ No newline at end of file
tags/rel_13/bench/data/extended_scancodes_set1.hex
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/bench/data/extended_scancodes_set2.hex
===================================================================
--- tags/rel_13/bench/data/extended_scancodes_set2.hex (nonexistent)
+++ tags/rel_13/bench/data/extended_scancodes_set2.hex (revision 42)
@@ -0,0 +1,38 @@
+1F
+14
+27
+11
+2F
+70
+6C
+7D
+71
+69
+7A
+75
+6B
+72
+74
+4A
+5A
+37
+3F
+5E
+4D
+15
+3B
+34
+23
+32
+21
+50
+48
+2B
+40
+10
+3A
+38
+30
+28
+20
+18
\ No newline at end of file
tags/rel_13/bench/data/extended_scancodes_set2.hex
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/bench/data/normal_scancodes_set1.hex
===================================================================
--- tags/rel_13/bench/data/normal_scancodes_set1.hex (nonexistent)
+++ tags/rel_13/bench/data/normal_scancodes_set1.hex (revision 42)
@@ -0,0 +1,85 @@
+1E
+30
+2E
+20
+12
+21
+22
+23
+17
+24
+25
+26
+32
+31
+18
+19
+10
+13
+1F
+14
+16
+2F
+11
+2D
+15
+2C
+0B
+02
+03
+04
+05
+06
+0A
+29
+0C
+0D
+2B
+0E
+39
+0F
+3A
+2A
+1D
+38
+36
+1C
+01
+3B
+3C
+3D
+3E
+3F
+40
+41
+42
+43
+44
+57
+58
+1A
+45
+37
+4A
+4E
+53
+52
+4F
+50
+51
+4B
+4C
+4D
+47
+48
+49
+1B
+27
+28
+33
+07
+08
+09
+46
+34
+35
\ No newline at end of file
tags/rel_13/bench/data/normal_scancodes_set1.hex
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/bench/data/normal_scancodes_set2.hex
===================================================================
--- tags/rel_13/bench/data/normal_scancodes_set2.hex (nonexistent)
+++ tags/rel_13/bench/data/normal_scancodes_set2.hex (revision 42)
@@ -0,0 +1,85 @@
+1C
+32
+21
+23
+24
+2B
+34
+33
+43
+3B
+42
+4B
+3A
+31
+44
+4D
+15
+2D
+1B
+2C
+3C
+2A
+1D
+22
+35
+1A
+45
+16
+1E
+26
+25
+2E
+46
+0E
+4E
+55
+5D
+66
+29
+0D
+58
+12
+14
+11
+59
+5A
+76
+05
+06
+04
+0C
+03
+0B
+83
+0A
+01
+09
+78
+07
+54
+77
+7C
+7B
+79
+71
+70
+69
+72
+7A
+6B
+73
+74
+6C
+75
+7D
+5B
+4C
+52
+41
+36
+3D
+3E
+7E
+49
+4A
\ No newline at end of file
tags/rel_13/bench/data/normal_scancodes_set2.hex
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/rtl/verilog/ps2_mouse.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_mouse.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_mouse.v (revision 42)
@@ -0,0 +1,523 @@
+//-------------------------------------------------------------------------------------
+//
+// Author: John Clayton
+// Date : April 30, 2001
+// Update: 4/30/01 copied this file from lcd_2.v (pared down).
+// Update: 5/24/01 changed the first module from "ps2_keyboard_receiver"
+// to "ps2_keyboard_interface"
+// Update: 5/29/01 Added input synchronizing flip-flops. Changed state
+// encoding (m1) for good operation after part config.
+// Update: 5/31/01 Added low drive strength and slow transitions to ps2_clk
+// and ps2_data in the constraints file. Added the signal
+// "tx_shifting_done" as distinguished from "rx_shifting_done."
+// Debugged the transmitter portion in the lab.
+// Update: 6/01/01 Added horizontal tab to the ascii output.
+// Update: 6/01/01 Added parameter TRAP_SHIFT_KEYS.
+// Update: 6/05/01 Debugged the "debounce" timer functionality.
+// Used 60usec timer as a "watchdog" timeout during
+// receive from the keyboard. This means that a keyboard
+// can now be "hot plugged" into the interface, without
+// messing up the bit_count, since the bit_count is reset
+// to zero during periods of inactivity anyway. This was
+// difficult to debug. I ended up using the logic analyzer,
+// and had to scratch my head quite a bit.
+// Update: 6/06/01 Removed extra comments before the input synchronizing
+// flip-flops. Used the correct parameter to size the
+// 5usec_timer_count. Changed the name of this file from
+// ps2.v to ps2_keyboard.v
+// Update: 6/06/01 Removed "&& q[7:0]" in output_strobe logic. Removed extra
+// commented out "else" condition in the shift register and
+// bit counter.
+// Update: 6/07/01 Changed default values for 60usec timer parameters so that
+// they correspond to 60usec for a 49.152MHz clock.
+//
+//
+//
+//
+//
+// Description
+//-------------------------------------------------------------------------------------
+// This is a state-machine driven serial-to-parallel and parallel-to-serial
+// interface to the ps2 style keyboard interface. The details of the operation
+// of the keyboard interface were obtained from the following website:
+//
+// http://www.beyondlogic.org/keyboard/keybrd.htm
+//
+// Some aspects of the keyboard interface are not implemented (e.g, parity
+// checking for the receive side, and recognition of the various commands
+// which the keyboard sends out, such as "power on selt test passed," "Error"
+// and "Resend.") However, if the user wishes to recognize these reply
+// messages, the scan code output can always be used to extend functionality
+// as desired.
+//
+// Note that the "Extended" (0xE0) and "Released" (0xF0) codes are recognized.
+// The rx interface provides separate indicator flags for these two conditions
+// with every valid character scan code which it provides. The shift keys are
+// also trapped by the interface, in order to provide correct uppercase ASCII
+// characters at the ascii output, although the scan codes for the shift keys
+// are still provided at the scan code output. So, the left/right ALT keys
+// can be differentiated by the presence of the rx_entended signal, while the
+// left/right shift keys are differentiable by the different scan codes
+// received.
+//
+// The interface to the ps2 keyboard uses ps2_clk clock rates of
+// 30-40 kHz, dependent upon the keyboard itself. The rate at which the state
+// machine runs should be at least twice the rate of the ps2_clk, so that the
+// states can accurately follow the clock signal itself. Four times
+// oversampling is better. Say 200kHz at least. The upper limit for clocking
+// the state machine will undoubtedly be determined by delays in the logic
+// which decodes the scan codes into ASCII equivalents. The maximum speed
+// will be most likely many megahertz, depending upon target technology.
+// In order to run the state machine extremely fast, synchronizing flip-flops
+// have been added to the ps2_clk and ps2_data inputs of the state machine.
+// This avoids poor performance related to slow transitions of the inputs.
+//
+// Because this is a bi-directional interface, while reading from the keyboard
+// the ps2_clk and ps2_data lines are used as inputs. While writing to the
+// keyboard, however (which may be done at any time. If writing interrupts a
+// read from the keyboard, the keyboard will buffer up its data, and send
+// it later) both the ps2_clk and ps2_data lines are occasionally pulled low,
+// and pullup resistors are used to bring the lines high again, by setting
+// the drivers to high impedance state.
+//
+// The tx interface, for writing to the keyboard, does not provide any special
+// pre-processing. It simply transmits the 8-bit command value to the
+// keyboard.
+//
+// Pullups MUST BE USED on the ps2_clk and ps2_data lines for this design,
+// whether they be internal to an FPGA I/O pad, or externally placed.
+// If internal pullups are used, they may be fairly weak, causing bounces
+// due to crosstalk, etc. There is a "debounce timer" implemented in order
+// to eliminate erroneous state transitions which would occur based on bounce.
+//
+// Parameters are provided in order to configure and appropriately size the
+// counter of a 60 microsecond timer used in the transmitter, depending on
+// the clock frequency used. The 60 microsecond period is guaranteed to be
+// more than one period of the ps2_clk_s signal.
+//
+// Also, a smaller 5 microsecond timer has been included for "debounce".
+// This is used because, with internal pullups on the ps2_clk and ps2_data
+// lines, there is some bouncing around which occurs
+//
+// A parameter TRAP_SHIFT_KEYS allows the user to eliminate shift keypresses
+// from producing scan codes (along with their "undefined" ASCII equivalents)
+// at the output of the interface. If TRAP_SHIFT_KEYS is non-zero, the shift
+// key status will only be reported by rx_shift_key_on. No ascii or scan
+// codes will be reported for the shift keys. This is useful for those who
+// wish to use the ASCII data stream, and who don't want to have to "filter
+// out" the shift key codes.
+//
+//-------------------------------------------------------------------------------------
+
+
+// synopsys translate_off
+`resetall
+`include "timescale.v"
+// synopsys translate_on
+`define TOTAL_BITS 11
+
+module ps2_mouse (
+ clk,
+ reset,
+ ps2_clk_en_o_,
+ ps2_data_en_o_,
+ ps2_clk_i,
+ ps2_data_i,
+ rx_scan_code,
+ rx_data_ready, // rx_read_o
+ rx_read, // rx_read_ack_i
+ tx_data,
+ tx_write,
+ tx_write_ack_o,
+ tx_error_no_ack,
+ devide_reg_i
+ );
+
+// Parameters
+
+// The timer value can be up to (2^bits) inclusive.
+parameter TIMER_60USEC_VALUE_PP = 2950; // Number of sys_clks for 60usec.
+parameter TIMER_60USEC_BITS_PP = 12; // Number of bits needed for timer
+parameter TIMER_5USEC_VALUE_PP = 186; // Number of sys_clks for debounce
+parameter TIMER_5USEC_BITS_PP = 8; // Number of bits needed for timer
+
+// State encodings, provided as parameters
+// for flexibility to the one instantiating the module.
+// In general, the default values need not be changed.
+
+// State "m1_rx_clk_l" has been chosen on purpose. Since the input
+// synchronizing flip-flops initially contain zero, it takes one clk
+// for them to update to reflect the actual (idle = high) status of
+// the I/O lines from the keyboard. Therefore, choosing 0 for m1_rx_clk_l
+// allows the state machine to transition to m1_rx_clk_h when the true
+// values of the input signals become present at the outputs of the
+// synchronizing flip-flops. This initial transition is harmless, and it
+// eliminates the need for a "reset" pulse before the interface can operate.
+
+parameter m1_rx_clk_h = 1;
+parameter m1_rx_clk_l = 0;
+parameter m1_rx_falling_edge_marker = 13;
+parameter m1_rx_rising_edge_marker = 14;
+parameter m1_tx_force_clk_l = 3;
+parameter m1_tx_first_wait_clk_h = 10;
+parameter m1_tx_first_wait_clk_l = 11;
+parameter m1_tx_reset_timer = 12;
+parameter m1_tx_wait_clk_h = 2;
+parameter m1_tx_clk_h = 4;
+parameter m1_tx_clk_l = 5;
+parameter m1_tx_wait_ack = 6;
+parameter m1_tx_done_recovery = 7;
+parameter m1_tx_error_no_ack = 8;
+parameter m1_tx_rising_edge_marker = 9;
+parameter m2_rx_data_ready = 1;
+parameter m2_rx_data_ready_ack = 0;
+
+
+// I/O declarations
+input clk;
+input reset;
+output ps2_clk_en_o_ ;
+output ps2_data_en_o_ ;
+input ps2_clk_i ;
+input ps2_data_i ;
+output [7:0] rx_scan_code;
+output rx_data_ready;
+input rx_read;
+input [7:0] tx_data;
+input tx_write;
+output tx_write_ack_o;
+output tx_error_no_ack;
+
+input [15:0] devide_reg_i;
+
+reg rx_released;
+reg [7:0] rx_scan_code;
+reg rx_data_ready;
+reg tx_error_no_ack;
+
+// Internal signal declarations
+wire timer_60usec_done;
+wire timer_5usec_done;
+reg timer_done ;
+reg timer_5usec ;
+ // NOTE: These two signals used to be one. They
+ // were split into two signals because of
+ // shift key trapping. With shift key
+ // trapping, no event is generated externally,
+ // but the "hold" data must still be cleared
+ // anyway regardless, in preparation for the
+ // next scan codes.
+wire rx_output_event; // Used only to clear: hold_released, hold_extended
+wire rx_output_strobe; // Used to produce the actual output.
+
+wire tx_parity_bit;
+wire rx_shifting_done;
+wire tx_shifting_done;
+
+reg [`TOTAL_BITS-1:0] q;
+reg [3:0] m1_state;
+reg [3:0] m1_next_state;
+reg m2_state;
+reg m2_next_state;
+reg [3:0] bit_count;
+reg enable_timer_60usec;
+reg enable_timer_5usec;
+reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
+reg [TIMER_5USEC_BITS_PP-1:0] timer_5usec_count;
+reg ps2_clk_s; // Synchronous version of this input
+reg ps2_data_s; // Synchronous version of this input
+reg ps2_clk_hi_z; // Without keyboard, high Z equals 1 due to pullups.
+reg ps2_data_hi_z; // Without keyboard, high Z equals 1 due to pullups.
+
+reg ps2_clk_ms;
+reg ps2_data_ms;
+
+//--------------------------------------------------------------------------
+// Module code
+
+assign ps2_clk_en_o_ = ps2_clk_hi_z ;
+assign ps2_data_en_o_ = ps2_data_hi_z ;
+
+// Input "synchronizing" logic -- synchronizes the inputs to the state
+// machine clock, thus avoiding errors related to
+// spurious state machine transitions.
+always @(posedge clk)
+begin
+ ps2_clk_ms <= #1 ps2_clk_i;
+ ps2_data_ms <= #1 ps2_data_i;
+
+ ps2_clk_s <= #1 ps2_clk_ms;
+ ps2_data_s <= #1 ps2_data_ms;
+
+end
+
+// State register
+always @(posedge clk)
+begin : m1_state_register
+ if (reset) m1_state <= #1 m1_rx_clk_h;
+ else m1_state <= #1 m1_next_state;
+end
+
+// State transition logic
+always @(m1_state
+ or q
+ or tx_shifting_done
+ or tx_write
+ or ps2_clk_s
+ or ps2_data_s
+ or timer_60usec_done
+ or timer_5usec_done
+ )
+begin : m1_state_logic
+
+ // Output signals default to this value, unless changed in a state condition.
+ ps2_clk_hi_z <= #1 1;
+ ps2_data_hi_z <= #1 1;
+ tx_error_no_ack <= #1 0;
+ enable_timer_60usec <= #1 0;
+ enable_timer_5usec <= #1 0;
+
+ case (m1_state)
+
+ m1_rx_clk_h :
+ begin
+ enable_timer_60usec <= #1 1;
+ if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
+ else if (~ps2_clk_s) m1_next_state <= #1 m1_rx_falling_edge_marker;
+ else m1_next_state <= #1 m1_rx_clk_h;
+ end
+
+ m1_rx_falling_edge_marker :
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_rx_clk_l;
+ end
+
+ m1_rx_rising_edge_marker :
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_rx_clk_h;
+ end
+
+
+ m1_rx_clk_l :
+ begin
+ enable_timer_60usec <= #1 1;
+ if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
+ else if (ps2_clk_s) m1_next_state <= #1 m1_rx_rising_edge_marker;
+ else m1_next_state <= #1 m1_rx_clk_l;
+ end
+
+ m1_tx_reset_timer:
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_tx_force_clk_l;
+ end
+
+ m1_tx_force_clk_l :
+ begin
+ enable_timer_60usec <= #1 1;
+ ps2_clk_hi_z <= #1 0; // Force the ps2_clk line low.
+ if (timer_60usec_done) m1_next_state <= #1 m1_tx_first_wait_clk_h;
+ else m1_next_state <= #1 m1_tx_force_clk_l;
+ end
+
+ m1_tx_first_wait_clk_h :
+ begin
+ enable_timer_5usec <= #1 1;
+ ps2_data_hi_z <= #1 0; // Start bit.
+ if (~ps2_clk_s && timer_5usec_done)
+ m1_next_state <= #1 m1_tx_clk_l;
+ else
+ m1_next_state <= #1 m1_tx_first_wait_clk_h;
+ end
+
+ // This state must be included because the device might possibly
+ // delay for up to 10 milliseconds before beginning its clock pulses.
+ // During that waiting time, we cannot drive the data (q[0]) because it
+ // is possibly 1, which would cause the keyboard to abort its receive
+ // and the expected clocks would then never be generated.
+ m1_tx_first_wait_clk_l :
+ begin
+ ps2_data_hi_z <= #1 0;
+ if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
+ else m1_next_state <= #1 m1_tx_first_wait_clk_l;
+ end
+
+ m1_tx_wait_clk_h :
+ begin
+ enable_timer_5usec <= #1 1;
+ ps2_data_hi_z <= #1 q[0];
+ if (ps2_clk_s && timer_5usec_done)
+ m1_next_state <= #1 m1_tx_rising_edge_marker;
+ else
+ m1_next_state <= #1 m1_tx_wait_clk_h;
+ end
+
+ m1_tx_rising_edge_marker :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ m1_next_state <= #1 m1_tx_clk_h;
+ end
+
+ m1_tx_clk_h :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ if (tx_shifting_done) m1_next_state <= #1 m1_tx_wait_ack;
+ else if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
+ else m1_next_state <= #1 m1_tx_clk_h;
+ end
+
+ m1_tx_clk_l :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ if (ps2_clk_s) m1_next_state <= #1 m1_tx_wait_clk_h;
+ else m1_next_state <= #1 m1_tx_clk_l;
+ end
+
+ m1_tx_wait_ack :
+ begin
+ if (~ps2_clk_s && ps2_data_s)
+ m1_next_state <= #1 m1_tx_error_no_ack;
+ else if (~ps2_clk_s && ~ps2_data_s)
+ m1_next_state <= #1 m1_tx_done_recovery;
+ else m1_next_state <= #1 m1_tx_wait_ack;
+ end
+
+ m1_tx_done_recovery :
+ begin
+ if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
+ else m1_next_state <= #1 m1_tx_done_recovery;
+ end
+
+ m1_tx_error_no_ack :
+ begin
+ tx_error_no_ack <= #1 1;
+ if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
+ else m1_next_state <= #1 m1_tx_error_no_ack;
+ end
+
+ default : m1_next_state <= #1 m1_rx_clk_h;
+ endcase
+end
+
+// State register
+always @(posedge clk)
+begin : m2_state_register
+ if (reset) m2_state <= #1 m2_rx_data_ready_ack;
+ else m2_state <= #1 m2_next_state;
+end
+
+// State transition logic
+always @(m2_state or rx_output_strobe or rx_read)
+begin : m2_state_logic
+ case (m2_state)
+ m2_rx_data_ready_ack:
+ begin
+ rx_data_ready <= #1 1'b0;
+ if (rx_output_strobe) m2_next_state <= #1 m2_rx_data_ready;
+ else m2_next_state <= #1 m2_rx_data_ready_ack;
+ end
+ m2_rx_data_ready:
+ begin
+ rx_data_ready <= #1 1'b1;
+ if (rx_read) m2_next_state <= #1 m2_rx_data_ready_ack;
+ else m2_next_state <= #1 m2_rx_data_ready;
+ end
+ default : m2_next_state <= #1 m2_rx_data_ready_ack;
+ endcase
+end
+
+// This is the bit counter
+always @(posedge clk)
+begin
+ if ( reset
+ || rx_shifting_done
+ || (m1_state == m1_tx_wait_ack) // After tx is done.
+ ) bit_count <= #1 0; // normal reset
+ else if (timer_60usec_done
+ && (m1_state == m1_rx_clk_h)
+ && (ps2_clk_s)
+ ) bit_count <= #1 0; // rx watchdog timer reset
+ else if ( (m1_state == m1_rx_falling_edge_marker) // increment for rx
+ ||(m1_state == m1_tx_rising_edge_marker) // increment for tx
+ )
+ bit_count <= #1 bit_count + 1;
+end
+// This signal is high for one clock at the end of the timer count.
+assign rx_shifting_done = (bit_count == `TOTAL_BITS);
+assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
+
+// This is the signal which enables loading of the shift register.
+// It also indicates "ack" to the device writing to the transmitter.
+assign tx_write_ack_o = ( (tx_write && (m1_state == m1_rx_clk_h))
+ ||(tx_write && (m1_state == m1_rx_clk_l))
+ );
+
+// This is the ODD parity bit for the transmitted word.
+assign tx_parity_bit = ~^tx_data;
+
+// This is the shift register
+always @(posedge clk)
+begin
+ if (reset) q <= #1 0;
+ else if (tx_write_ack_o) q <= #1 {1'b1,tx_parity_bit,tx_data,1'b0};
+ else if ( (m1_state == m1_rx_falling_edge_marker)
+ ||(m1_state == m1_tx_rising_edge_marker) )
+ q <= #1 {ps2_data_s,q[`TOTAL_BITS-1:1]};
+end
+
+// This is the 60usec timer counter
+always @(posedge clk)
+begin
+ if (~enable_timer_60usec) timer_60usec_count <= #1 0;
+ else if ( timer_done && !timer_60usec_done)
+ timer_60usec_count<= #1 timer_60usec_count +1;
+ end
+assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP ));
+
+
+
+always @(posedge clk or posedge reset)
+if (reset) timer_5usec <= #1 1;
+else if (!enable_timer_60usec) timer_5usec <= #1 1;
+else if (timer_5usec == devide_reg_i)
+ begin
+ timer_5usec <= #1 1;
+ timer_done <= #1 1;
+ end
+else
+ begin
+ timer_5usec<= #1 timer_5usec +1;
+ timer_done <= #1 0;
+ end
+
+// This is the 5usec timer counter
+always @(posedge clk)
+begin
+ if (~enable_timer_5usec) timer_5usec_count <= #1 0;
+ else if (~timer_5usec_done) timer_5usec_count <= #1 timer_5usec_count + 1;
+end
+assign timer_5usec_done = (timer_5usec_count == devide_reg_i - 1);
+
+always @(posedge clk)
+begin
+ if (reset)
+ begin
+ rx_scan_code <= #1 0;
+ end
+ else if (rx_output_strobe)
+ begin
+ rx_scan_code <= #1 q[8:1];
+ end
+end
+
+// Store the final rx output data only when all extend and release codes
+// are received and the next (actual key) scan code is also ready.
+// (the presence of rx_extended or rx_released refers to the
+// the current latest scan code received, not the previously latched flags.)
+assign rx_output_event = rx_shifting_done ;
+
+assign rx_output_strobe = rx_shifting_done ;
+
+endmodule
tags/rel_13/rtl/verilog/ps2_mouse.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/rtl/verilog/ps2_wb_if.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_wb_if.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_wb_if.v (revision 42)
@@ -0,0 +1,727 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_wb_if.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.7 2003/10/03 10:16:52 primozs
+// support for configurable devider added
+//
+// Revision 1.6 2003/05/28 16:27:09 simons
+// Change the address width.
+//
+// Revision 1.5 2002/04/09 13:24:11 mihad
+// Added mouse interface and everything for its handling, cleaned up some unused code
+//
+// Revision 1.4 2002/02/20 16:35:43 mihad
+// Little/big endian changes continued
+//
+// Revision 1.3 2002/02/20 15:20:10 mihad
+// Little/big endian changes incorporated
+//
+// Revision 1.2 2002/02/18 18:07:55 mihad
+// One bug fixed
+//
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+module ps2_wb_if
+(
+ wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i,
+ wb_sel_i,
+ wb_adr_i,
+ wb_dat_i,
+ wb_dat_o,
+ wb_ack_o,
+
+ wb_int_o,
+
+ tx_kbd_write_ack_i,
+ tx_kbd_data_o,
+ tx_kbd_write_o,
+ rx_scancode_i,
+ rx_kbd_data_ready_i,
+ rx_kbd_read_o,
+ translate_o,
+ ps2_kbd_clk_i,
+ devide_reg_o,
+ inhibit_kbd_if_o
+ `ifdef PS2_AUX
+ ,
+ wb_intb_o,
+
+ rx_aux_data_i,
+ rx_aux_data_ready_i,
+ rx_aux_read_o,
+ tx_aux_data_o,
+ tx_aux_write_o,
+ tx_aux_write_ack_i,
+ ps2_aux_clk_i,
+ inhibit_aux_if_o
+`endif
+) ;
+
+input wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i ;
+
+input [3:0] wb_sel_i ;
+
+input [3:0] wb_adr_i ;
+
+input [31:0] wb_dat_i ;
+
+output [31:0] wb_dat_o ;
+
+output wb_ack_o ;
+
+reg wb_ack_o ;
+
+output wb_int_o ;
+reg wb_int_o ;
+
+input tx_kbd_write_ack_i ;
+
+input [7:0] rx_scancode_i ;
+input rx_kbd_data_ready_i ;
+output rx_kbd_read_o ;
+
+output tx_kbd_write_o ;
+output [7:0] tx_kbd_data_o ;
+
+output translate_o ;
+input ps2_kbd_clk_i ;
+
+output inhibit_kbd_if_o ;
+
+reg [7:0] input_buffer,
+ output_buffer ;
+
+output [15:0] devide_reg_o;
+reg [15:0] devide_reg;
+assign devide_reg_o = devide_reg;
+
+
+reg [15:0] wb_dat_i_sampled ;
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ wb_dat_i_sampled <= #1 0 ;
+ else if ( wb_cyc_i && wb_stb_i && wb_we_i )
+ wb_dat_i_sampled <= #1 wb_dat_i[31:16] ;
+end
+
+`ifdef PS2_AUX
+output wb_intb_o ;
+reg wb_intb_o ;
+
+input [7:0] rx_aux_data_i ;
+input rx_aux_data_ready_i ;
+output rx_aux_read_o ;
+output [7:0] tx_aux_data_o ;
+output tx_aux_write_o ;
+input tx_aux_write_ack_i ;
+input ps2_aux_clk_i ;
+output inhibit_aux_if_o ;
+reg inhibit_aux_if_o ;
+reg aux_output_buffer_full ;
+reg aux_input_buffer_full ;
+reg interrupt2 ;
+reg enable2 ;
+assign tx_aux_data_o = output_buffer ;
+assign tx_aux_write_o = aux_output_buffer_full ;
+`else
+wire aux_input_buffer_full = 1'b0 ;
+wire aux_output_buffer_full = 1'b0 ;
+wire interrupt2 = 1'b0 ;
+wire enable2 = 1'b1 ;
+`endif
+
+assign tx_kbd_data_o = output_buffer ;
+
+reg input_buffer_full, // receive buffer
+ output_buffer_full ; // transmit buffer
+
+assign tx_kbd_write_o = output_buffer_full ;
+
+wire system_flag ;
+wire a2 = 1'b0 ;
+wire kbd_inhibit = ps2_kbd_clk_i ;
+wire timeout = 1'b0 ;
+wire perr = 1'b0 ;
+
+wire [7:0] status_byte = {perr, timeout, aux_input_buffer_full, kbd_inhibit, a2, system_flag, output_buffer_full || aux_output_buffer_full, input_buffer_full} ;
+
+reg read_input_buffer_reg ;
+wire read_input_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_input_buffer_reg && !wb_we_i && (wb_adr_i[3:0] == 4'h0) ;
+
+reg write_output_buffer_reg ;
+wire write_output_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !write_output_buffer_reg && wb_we_i && (wb_adr_i[3:0] == 4'h0) ;
+
+reg read_status_register_reg ;
+wire read_status_register = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_status_register_reg && !wb_we_i && (wb_adr_i[3:0] == 4'h4) ;
+
+reg send_command_reg ;
+wire send_command = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !send_command_reg && wb_we_i && (wb_adr_i[3:0] == 4'h4) ;
+
+reg write_devide_reg0 ;
+wire write_devide0 = wb_cyc_i && wb_stb_i && wb_sel_i[2] && !wb_ack_o && !write_devide_reg0 && wb_we_i && (wb_adr_i[3:0] == 4'h8) ;
+
+//reg read_devide_reg ;
+wire read_devide = wb_cyc_i && wb_stb_i && ( wb_sel_i[2]|| wb_sel_i [3] ) && !wb_we_i && (wb_adr_i[3:0] == 4'h8) ;
+
+reg write_devide_reg1 ;
+wire write_devide1 = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !write_devide_reg1 && wb_we_i && (wb_adr_i[3:0] == 4'h8) ;
+
+
+reg translate_o,
+ enable1,
+ system,
+ interrupt1 ;
+
+reg inhibit_kbd_if_o ;
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ inhibit_kbd_if_o <= #1 1'b0 ;
+ else if ( ps2_kbd_clk_i && rx_kbd_data_ready_i && !enable1)
+ inhibit_kbd_if_o <= #1 1'b1 ;
+ else if ( !rx_kbd_data_ready_i || enable1 )
+ inhibit_kbd_if_o <= #1 1'b0 ;
+
+end
+
+`ifdef PS2_AUX
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ inhibit_aux_if_o <= #1 1'b1 ;
+ else if ( ps2_aux_clk_i && rx_aux_data_ready_i && !enable2 )
+ inhibit_aux_if_o <= #1 1'b1 ;
+ else if ( !rx_aux_data_ready_i || enable2 )
+ inhibit_aux_if_o <= #1 1'b0 ;
+
+end
+`endif
+
+assign system_flag = system ;
+
+wire [7:0] command_byte = {1'b0, translate_o, enable2, enable1, 1'b0, system, interrupt2, interrupt1} ;
+
+reg [7:0] current_command ;
+reg [7:0] current_command_output ;
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ begin
+ send_command_reg <= #1 1'b0 ;
+ read_input_buffer_reg <= #1 1'b0 ;
+ write_output_buffer_reg <= #1 1'b0 ;
+ read_status_register_reg <= #1 1'b0 ;
+ write_devide_reg0 <= #1 1'b0 ;
+ //read_devide_reg <= #1 1'b0 ;
+ write_devide_reg1 <= #1 1'b0 ;
+ end
+ else
+ begin
+ send_command_reg <= #1 send_command ;
+ read_input_buffer_reg <= #1 read_input_buffer ;
+ write_output_buffer_reg <= #1 write_output_buffer ;
+ read_status_register_reg <= #1 read_status_register ;
+ write_devide_reg0 <= #1 write_devide0 ;
+ //read_devide_reg <= #1 read_devide ;
+ write_devide_reg1 <= #1 write_devide1 ;
+ end
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ current_command <= #1 8'h0 ;
+ else if ( send_command_reg )
+ current_command <= #1 wb_dat_i_sampled[15:8] ;
+end
+
+reg current_command_valid,
+ current_command_returns_value,
+ current_command_gets_parameter,
+ current_command_gets_null_terminated_string ;
+
+reg write_output_buffer_reg_previous ;
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ write_output_buffer_reg_previous <= #1 1'b0 ;
+ else
+ write_output_buffer_reg_previous <= #1 write_output_buffer_reg ;
+end
+
+wire invalidate_current_command =
+ current_command_valid &&
+ (( current_command_returns_value && read_input_buffer_reg && input_buffer_full) ||
+ ( current_command_gets_parameter && write_output_buffer_reg_previous ) ||
+ ( current_command_gets_null_terminated_string && write_output_buffer_reg_previous && (output_buffer == 8'h00) ) ||
+ ( !current_command_returns_value && !current_command_gets_parameter && !current_command_gets_null_terminated_string )
+ ) ;
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ current_command_valid <= #1 1'b0 ;
+ else if ( invalidate_current_command )
+ current_command_valid <= #1 1'b0 ;
+ else if ( send_command_reg )
+ current_command_valid <= #1 1'b1 ;
+
+end
+
+reg write_command_byte ;
+reg current_command_output_valid ;
+always@(
+ current_command or
+ command_byte or
+ write_output_buffer_reg_previous or
+ current_command_valid or
+ output_buffer
+)
+begin
+ current_command_returns_value = 1'b0 ;
+ current_command_gets_parameter = 1'b0 ;
+ current_command_gets_null_terminated_string = 1'b0 ;
+ current_command_output = 8'h00 ;
+ write_command_byte = 1'b0 ;
+ current_command_output_valid = 1'b0 ;
+ case(current_command)
+ 8'h20:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = command_byte ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'h60:begin
+ current_command_gets_parameter = 1'b1 ;
+ write_command_byte = write_output_buffer_reg_previous && current_command_valid ;
+ end
+ 8'hA1:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'h00 ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hA4:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'hF1 ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hA5:begin
+ current_command_gets_null_terminated_string = 1'b1 ;
+ end
+ 8'hA6:begin
+ end
+ 8'hA7:begin
+ end
+ 8'hA8:begin
+ end
+ 8'hA9:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output_valid = 1'b1 ;
+ `ifdef PS2_AUX
+ current_command_output = 8'h00 ; // interface OK
+ `else
+ current_command_output = 8'h02 ; // clock line stuck high
+ `endif
+ end
+ 8'hAA:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'h55 ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hAB:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'h00 ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hAD:begin
+ end
+ 8'hAE:begin
+ end
+ 8'hAF:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'h00 ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hC0:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'hFF ;
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hC1:begin
+ end
+ 8'hC2:begin
+ end
+ 8'hD0:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'h01 ; // only system reset bit is 1
+ current_command_output_valid = 1'b1 ;
+ end
+ 8'hD1:begin
+ current_command_gets_parameter = 1'b1 ;
+ end
+ 8'hD2:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_gets_parameter = 1'b1 ;
+ current_command_output = output_buffer ;
+ current_command_output_valid = write_output_buffer_reg_previous ;
+ end
+ 8'hD3:begin
+ current_command_gets_parameter = 1'b1 ;
+ `ifdef PS2_AUX
+ current_command_returns_value = 1'b1 ;
+ current_command_output = output_buffer ;
+ current_command_output_valid = write_output_buffer_reg_previous ;
+ `endif
+ end
+ 8'hD4:begin
+ current_command_gets_parameter = 1'b1 ;
+ end
+ 8'hE0:begin
+ current_command_returns_value = 1'b1 ;
+ current_command_output = 8'hFF ;
+ current_command_output_valid = 1'b1 ;
+ end
+ endcase
+end
+
+reg cyc_i_previous ;
+reg stb_i_previous ;
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ begin
+ cyc_i_previous <= #1 1'b0 ;
+ stb_i_previous <= #1 1'b0 ;
+ end
+ else if ( wb_ack_o )
+ begin
+ cyc_i_previous <= #1 1'b0 ;
+ stb_i_previous <= #1 1'b0 ;
+ end
+ else
+ begin
+ cyc_i_previous <= #1 wb_cyc_i ;
+ stb_i_previous <= #1 wb_stb_i ;
+ end
+
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ wb_ack_o <= #1 1'b0 ;
+ else if ( wb_ack_o )
+ wb_ack_o <= #1 1'b0 ;
+ else
+ wb_ack_o <= #1 cyc_i_previous && stb_i_previous ;
+end
+
+reg [31:0] wb_dat_o ;
+wire wb_read = read_input_buffer_reg || read_status_register_reg || read_devide ;
+
+wire [15:0] output_data = read_status_register_reg ? {2{status_byte}} : read_devide ? devide_reg : {2{input_buffer}} ;
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ wb_dat_o <= #1 32'h0 ;
+ else if ( wb_read )
+ wb_dat_o <= #1 {2{output_data}} ;
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ output_buffer_full <= #1 1'b0 ;
+ else if ( output_buffer_full && tx_kbd_write_ack_i || enable1)
+ output_buffer_full <= #1 1'b0 ;
+ else
+ output_buffer_full <= #1 write_output_buffer_reg && (!current_command_valid || (!current_command_gets_parameter && !current_command_gets_null_terminated_string)) ;
+end
+
+`ifdef PS2_AUX
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ aux_output_buffer_full <= #1 1'b0 ;
+ else if ( aux_output_buffer_full && tx_aux_write_ack_i || enable2)
+ aux_output_buffer_full <= #1 1'b0 ;
+ else
+ aux_output_buffer_full <= #1 write_output_buffer_reg && current_command_valid && (current_command == 8'hD4) ;
+end
+`endif
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ output_buffer <= #1 8'h00 ;
+ else if ( write_output_buffer_reg )
+ output_buffer <= #1 wb_dat_i_sampled[15:8];
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ devide_reg <= #1 8'h00 ;
+ else
+ begin
+ if ( write_devide_reg0 )
+ devide_reg[7:0] <= #1 wb_dat_i_sampled[7:0] ;
+ if ( write_devide_reg1 )
+ devide_reg[15:8] <= #1 wb_dat_i_sampled[15:8] ;
+ end
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ begin
+ translate_o <= #1 1'b0 ;
+ system <= #1 1'b0 ;
+ interrupt1 <= #1 1'b0 ;
+ `ifdef PS2_AUX
+ interrupt2 <= #1 1'b0 ;
+ `endif
+ end
+ else if ( write_command_byte )
+ begin
+ translate_o <= #1 output_buffer[6] ;
+ system <= #1 output_buffer[2] ;
+ interrupt1 <= #1 output_buffer[0] ;
+ `ifdef PS2_AUX
+ interrupt2 <= #1 output_buffer[1] ;
+ `endif
+ end
+end
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ enable1 <= #1 1'b1 ;
+ else if ( current_command_valid && (current_command == 8'hAE) )
+ enable1 <= #1 1'b0 ;
+ else if ( current_command_valid && (current_command == 8'hAD) )
+ enable1 <= #1 1'b1 ;
+ else if ( write_command_byte )
+ enable1 <= #1 output_buffer[4] ;
+
+end
+
+`ifdef PS2_AUX
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ enable2 <= #1 1'b1 ;
+ else if ( current_command_valid && (current_command == 8'hA8) )
+ enable2 <= #1 1'b0 ;
+ else if ( current_command_valid && (current_command == 8'hA7) )
+ enable2 <= #1 1'b1 ;
+ else if ( write_command_byte )
+ enable2 <= #1 output_buffer[5] ;
+
+end
+`endif
+
+wire write_input_buffer_from_command = current_command_valid && current_command_returns_value && current_command_output_valid ;
+wire write_input_buffer_from_kbd = !input_buffer_full && rx_kbd_data_ready_i && !enable1 && !current_command_valid ;
+
+`ifdef PS2_AUX
+wire write_input_buffer_from_aux = !input_buffer_full && rx_aux_data_ready_i && !enable2 && !current_command_valid && !write_input_buffer_from_kbd ;
+`endif
+
+wire load_input_buffer_value =
+ write_input_buffer_from_command
+ ||
+ write_input_buffer_from_kbd
+ `ifdef PS2_AUX
+ ||
+ write_input_buffer_from_aux
+ `endif
+ ;
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ input_buffer_full <= #1 1'b0 ;
+ else if ( read_input_buffer_reg )
+ input_buffer_full <= #1 1'b0 ;
+ else if ( load_input_buffer_value )
+ input_buffer_full <= #1 1'b1 ;
+end
+
+`ifdef PS2_AUX
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ aux_input_buffer_full <= #1 1'b0 ;
+ else if ( read_input_buffer_reg )
+ aux_input_buffer_full <= #1 1'b0 ;
+ else if ( write_input_buffer_from_aux || (write_input_buffer_from_command && (current_command == 8'hD3)) )
+ aux_input_buffer_full <= #1 1'b1 ;
+end
+`endif
+
+reg input_buffer_filled_from_command ;
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ input_buffer_filled_from_command <= #1 1'b0 ;
+ else if ( read_input_buffer_reg )
+ input_buffer_filled_from_command <= #1 1'b0 ;
+ else if ( write_input_buffer_from_command )
+ input_buffer_filled_from_command <= #1 1'b1 ;
+end
+
+`ifdef PS2_AUX
+reg [7:0] value_to_load_in_input_buffer ;
+always@
+(
+ write_input_buffer_from_command
+ or
+ current_command_output
+ or
+ rx_scancode_i
+ or
+ write_input_buffer_from_kbd
+ or
+ rx_aux_data_i
+)
+begin
+ case ({write_input_buffer_from_command, write_input_buffer_from_kbd})
+ 2'b10,
+ 2'b11 : value_to_load_in_input_buffer = current_command_output ;
+ 2'b01 : value_to_load_in_input_buffer = rx_scancode_i ;
+ 2'b00 : value_to_load_in_input_buffer = rx_aux_data_i ;
+ endcase
+end
+
+`else
+wire [7:0] value_to_load_in_input_buffer = write_input_buffer_from_command ? current_command_output : rx_scancode_i ;
+`endif
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ input_buffer <= #1 8'h00 ;
+ else if ( load_input_buffer_value )
+ input_buffer <= #1 value_to_load_in_input_buffer ;
+end
+
+assign rx_kbd_read_o = rx_kbd_data_ready_i &&
+ ( enable1
+ ||
+ ( read_input_buffer_reg
+ &&
+ input_buffer_full
+ &&
+ !input_buffer_filled_from_command
+ `ifdef PS2_AUX
+ &&
+ !aux_input_buffer_full
+ `endif
+ )
+ );
+
+`ifdef PS2_AUX
+assign rx_aux_read_o = rx_aux_data_ready_i &&
+ ( enable2 ||
+ ( read_input_buffer_reg
+ &&
+ input_buffer_full
+ &&
+ aux_input_buffer_full
+ &&
+ !input_buffer_filled_from_command
+ )
+ );
+`endif
+
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ wb_int_o <= #1 1'b0 ;
+ else if ( read_input_buffer_reg || enable1 || !interrupt1)
+ wb_int_o <= #1 1'b0 ;
+ else
+ wb_int_o <= #1 input_buffer_full
+ `ifdef PS2_AUX
+ &&
+ !aux_input_buffer_full
+ `endif
+ ;
+end
+
+`ifdef PS2_AUX
+always@(posedge wb_clk_i or posedge wb_rst_i)
+begin
+ if ( wb_rst_i )
+ wb_intb_o <= #1 1'b0 ;
+ else if ( read_input_buffer_reg || enable2 || !interrupt2)
+ wb_intb_o <= #1 1'b0 ;
+ else
+ wb_intb_o <= #1 input_buffer_full
+ &&
+ aux_input_buffer_full
+ ;
+end
+`endif
+
+endmodule // ps2_wb_if
Index: tags/rel_13/rtl/verilog/ps2_keyboard.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_keyboard.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_keyboard.v (revision 42)
@@ -0,0 +1,568 @@
+//-------------------------------------------------------------------------------------
+//
+// Author: John Clayton
+// Date : April 30, 2001
+// Update: 4/30/01 copied this file from lcd_2.v (pared down).
+// Update: 5/24/01 changed the first module from "ps2_keyboard_receiver"
+// to "ps2_keyboard_interface"
+// Update: 5/29/01 Added input synchronizing flip-flops. Changed state
+// encoding (m1) for good operation after part config.
+// Update: 5/31/01 Added low drive strength and slow transitions to ps2_clk
+// and ps2_data in the constraints file. Added the signal
+// "tx_shifting_done" as distinguished from "rx_shifting_done."
+// Debugged the transmitter portion in the lab.
+// Update: 6/01/01 Added horizontal tab to the ascii output.
+// Update: 6/01/01 Added parameter TRAP_SHIFT_KEYS.
+// Update: 6/05/01 Debugged the "debounce" timer functionality.
+// Used 60usec timer as a "watchdog" timeout during
+// receive from the keyboard. This means that a keyboard
+// can now be "hot plugged" into the interface, without
+// messing up the bit_count, since the bit_count is reset
+// to zero during periods of inactivity anyway. This was
+// difficult to debug. I ended up using the logic analyzer,
+// and had to scratch my head quite a bit.
+// Update: 6/06/01 Removed extra comments before the input synchronizing
+// flip-flops. Used the correct parameter to size the
+// 5usec_timer_count. Changed the name of this file from
+// ps2.v to ps2_keyboard.v
+// Update: 6/06/01 Removed "&& q[7:0]" in output_strobe logic. Removed extra
+// commented out "else" condition in the shift register and
+// bit counter.
+// Update: 6/07/01 Changed default values for 60usec timer parameters so that
+// they correspond to 60usec for a 49.152MHz clock.
+//
+//
+//
+//
+//
+// Description
+//-------------------------------------------------------------------------------------
+// This is a state-machine driven serial-to-parallel and parallel-to-serial
+// interface to the ps2 style keyboard interface. The details of the operation
+// of the keyboard interface were obtained from the following website:
+//
+// http://www.beyondlogic.org/keyboard/keybrd.htm
+//
+// Some aspects of the keyboard interface are not implemented (e.g, parity
+// checking for the receive side, and recognition of the various commands
+// which the keyboard sends out, such as "power on selt test passed," "Error"
+// and "Resend.") However, if the user wishes to recognize these reply
+// messages, the scan code output can always be used to extend functionality
+// as desired.
+//
+// Note that the "Extended" (0xE0) and "Released" (0xF0) codes are recognized.
+// The rx interface provides separate indicator flags for these two conditions
+// with every valid character scan code which it provides. The shift keys are
+// also trapped by the interface, in order to provide correct uppercase ASCII
+// characters at the ascii output, although the scan codes for the shift keys
+// are still provided at the scan code output. So, the left/right ALT keys
+// can be differentiated by the presence of the rx_entended signal, while the
+// left/right shift keys are differentiable by the different scan codes
+// received.
+//
+// The interface to the ps2 keyboard uses ps2_clk clock rates of
+// 30-40 kHz, dependent upon the keyboard itself. The rate at which the state
+// machine runs should be at least twice the rate of the ps2_clk, so that the
+// states can accurately follow the clock signal itself. Four times
+// oversampling is better. Say 200kHz at least. The upper limit for clocking
+// the state machine will undoubtedly be determined by delays in the logic
+// which decodes the scan codes into ASCII equivalents. The maximum speed
+// will be most likely many megahertz, depending upon target technology.
+// In order to run the state machine extremely fast, synchronizing flip-flops
+// have been added to the ps2_clk and ps2_data inputs of the state machine.
+// This avoids poor performance related to slow transitions of the inputs.
+//
+// Because this is a bi-directional interface, while reading from the keyboard
+// the ps2_clk and ps2_data lines are used as inputs. While writing to the
+// keyboard, however (which may be done at any time. If writing interrupts a
+// read from the keyboard, the keyboard will buffer up its data, and send
+// it later) both the ps2_clk and ps2_data lines are occasionally pulled low,
+// and pullup resistors are used to bring the lines high again, by setting
+// the drivers to high impedance state.
+//
+// The tx interface, for writing to the keyboard, does not provide any special
+// pre-processing. It simply transmits the 8-bit command value to the
+// keyboard.
+//
+// Pullups MUST BE USED on the ps2_clk and ps2_data lines for this design,
+// whether they be internal to an FPGA I/O pad, or externally placed.
+// If internal pullups are used, they may be fairly weak, causing bounces
+// due to crosstalk, etc. There is a "debounce timer" implemented in order
+// to eliminate erroneous state transitions which would occur based on bounce.
+//
+// Parameters are provided in order to configure and appropriately size the
+// counter of a 60 microsecond timer used in the transmitter, depending on
+// the clock frequency used. The 60 microsecond period is guaranteed to be
+// more than one period of the ps2_clk_s signal.
+//
+// Also, a smaller 5 microsecond timer has been included for "debounce".
+// This is used because, with internal pullups on the ps2_clk and ps2_data
+// lines, there is some bouncing around which occurs
+//
+// A parameter TRAP_SHIFT_KEYS allows the user to eliminate shift keypresses
+// from producing scan codes (along with their "undefined" ASCII equivalents)
+// at the output of the interface. If TRAP_SHIFT_KEYS is non-zero, the shift
+// key status will only be reported by rx_shift_key_on. No ascii or scan
+// codes will be reported for the shift keys. This is useful for those who
+// wish to use the ASCII data stream, and who don't want to have to "filter
+// out" the shift key codes.
+//
+//-------------------------------------------------------------------------------------
+
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+`define TOTAL_BITS 11
+`define RELEASE_CODE 16'hF0
+
+module ps2_keyboard (
+ clk,
+ reset,
+ ps2_clk_en_o_,
+ ps2_data_en_o_,
+ ps2_clk_i,
+ ps2_data_i,
+ rx_released,
+ rx_scan_code,
+ rx_data_ready, // rx_read_o
+ rx_read, // rx_read_ack_i
+ tx_data,
+ tx_write,
+ tx_write_ack_o,
+ tx_error_no_keyboard_ack,
+ translate,
+ devide_reg_i
+ );
+
+// Parameters
+
+
+// The timer value can be up to (2^bits) inclusive.
+parameter TIMER_60USEC_VALUE_PP = 2950; // Number of sys_clks for 60usec.
+parameter TIMER_60USEC_BITS_PP = 12; // Number of bits needed for timer
+parameter TIMER_5USEC_VALUE_PP = 186; // Number of sys_clks for debounce
+parameter TIMER_5USEC_BITS_PP = 8; // Number of bits needed for timer
+
+// State encodings, provided as parameters
+// for flexibility to the one instantiating the module.
+// In general, the default values need not be changed.
+
+// State "m1_rx_clk_l" has been chosen on purpose. Since the input
+// synchronizing flip-flops initially contain zero, it takes one clk
+// for them to update to reflect the actual (idle = high) status of
+// the I/O lines from the keyboard. Therefore, choosing 0 for m1_rx_clk_l
+// allows the state machine to transition to m1_rx_clk_h when the true
+// values of the input signals become present at the outputs of the
+// synchronizing flip-flops. This initial transition is harmless, and it
+// eliminates the need for a "reset" pulse before the interface can operate.
+
+parameter m1_rx_clk_h = 1;
+parameter m1_rx_clk_l = 0;
+parameter m1_rx_falling_edge_marker = 13;
+parameter m1_rx_rising_edge_marker = 14;
+parameter m1_tx_force_clk_l = 3;
+parameter m1_tx_first_wait_clk_h = 10;
+parameter m1_tx_first_wait_clk_l = 11;
+parameter m1_tx_reset_timer = 12;
+parameter m1_tx_wait_clk_h = 2;
+parameter m1_tx_clk_h = 4;
+parameter m1_tx_clk_l = 5;
+parameter m1_tx_wait_keyboard_ack = 6;
+parameter m1_tx_done_recovery = 7;
+parameter m1_tx_error_no_keyboard_ack = 8;
+parameter m1_tx_rising_edge_marker = 9;
+parameter m2_rx_data_ready = 1;
+parameter m2_rx_data_ready_ack = 0;
+
+
+// I/O declarations
+input clk;
+input reset;
+output ps2_clk_en_o_ ;
+output ps2_data_en_o_ ;
+input ps2_clk_i ;
+input ps2_data_i ;
+output rx_released;
+output [7:0] rx_scan_code;
+output rx_data_ready;
+input rx_read;
+input [7:0] tx_data;
+input tx_write;
+output tx_write_ack_o;
+output tx_error_no_keyboard_ack;
+input translate ;
+
+input [15:0] devide_reg_i;
+
+reg rx_released;
+reg [7:0] rx_scan_code;
+reg rx_data_ready;
+reg tx_error_no_keyboard_ack;
+
+// Internal signal declarations
+wire timer_60usec_done;
+wire timer_5usec_done;
+wire released;
+
+ // NOTE: These two signals used to be one. They
+ // were split into two signals because of
+ // shift key trapping. With shift key
+ // trapping, no event is generated externally,
+ // but the "hold" data must still be cleared
+ // anyway regardless, in preparation for the
+ // next scan codes.
+wire rx_output_event; // Used only to clear: hold_released, hold_extended
+wire rx_output_strobe; // Used to produce the actual output.
+
+wire tx_parity_bit;
+wire rx_shifting_done;
+wire tx_shifting_done;
+
+reg [`TOTAL_BITS-1:0] q;
+reg [3:0] m1_state;
+reg [3:0] m1_next_state;
+reg m2_state;
+reg m2_next_state;
+reg [3:0] bit_count;
+reg enable_timer_60usec;
+reg enable_timer_5usec;
+reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
+reg [TIMER_5USEC_BITS_PP-1:0] timer_5usec_count;
+reg hold_released; // Holds prior value, cleared at rx_output_strobe
+reg ps2_clk_s; // Synchronous version of this input
+reg ps2_data_s; // Synchronous version of this input
+reg ps2_clk_hi_z; // Without keyboard, high Z equals 1 due to pullups.
+reg ps2_data_hi_z; // Without keyboard, high Z equals 1 due to pullups.
+reg ps2_clk_ms;
+reg ps2_data_ms;
+
+
+reg [15:0] timer_5usec;
+reg timer_done;
+
+
+
+//--------------------------------------------------------------------------
+// Module code
+
+assign ps2_clk_en_o_ = ps2_clk_hi_z ;
+assign ps2_data_en_o_ = ps2_data_hi_z ;
+
+// Input "synchronizing" logic -- synchronizes the inputs to the state
+// machine clock, thus avoiding errors related to
+// spurious state machine transitions.
+always @(posedge clk)
+begin
+ ps2_clk_ms <= #1 ps2_clk_i;
+ ps2_data_ms <= #1 ps2_data_i;
+
+ ps2_clk_s <= #1 ps2_clk_ms;
+ ps2_data_s <= #1 ps2_data_ms;
+
+end
+
+// State register
+always @(posedge clk or posedge reset)
+begin : m1_state_register
+ if (reset) m1_state <= #1 m1_rx_clk_h;
+ else m1_state <= #1 m1_next_state;
+end
+
+// State transition logic
+always @(m1_state
+ or q
+ or tx_shifting_done
+ or tx_write
+ or ps2_clk_s
+ or ps2_data_s
+ or timer_60usec_done
+ or timer_5usec_done
+ )
+begin : m1_state_logic
+
+ // Output signals default to this value, unless changed in a state condition.
+ ps2_clk_hi_z <= #1 1;
+ ps2_data_hi_z <= #1 1;
+ tx_error_no_keyboard_ack <= #1 1'b0;
+ enable_timer_60usec <= #1 0;
+ enable_timer_5usec <= #1 0;
+
+ case (m1_state)
+
+ m1_rx_clk_h :
+ begin
+ enable_timer_60usec <= #1 1;
+ if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
+ else if (~ps2_clk_s) m1_next_state <= #1 m1_rx_falling_edge_marker;
+ else m1_next_state <= #1 m1_rx_clk_h;
+ end
+
+ m1_rx_falling_edge_marker :
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_rx_clk_l;
+ end
+
+ m1_rx_rising_edge_marker :
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_rx_clk_h;
+ end
+
+
+ m1_rx_clk_l :
+ begin
+ enable_timer_60usec <= #1 1;
+ if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
+ else if (ps2_clk_s) m1_next_state <= #1 m1_rx_rising_edge_marker;
+ else m1_next_state <= #1 m1_rx_clk_l;
+ end
+
+ m1_tx_reset_timer:
+ begin
+ enable_timer_60usec <= #1 0;
+ m1_next_state <= #1 m1_tx_force_clk_l;
+ end
+
+ m1_tx_force_clk_l :
+ begin
+ enable_timer_60usec <= #1 1;
+ ps2_clk_hi_z <= #1 0; // Force the ps2_clk line low.
+ if (timer_60usec_done) m1_next_state <= #1 m1_tx_first_wait_clk_h;
+ else m1_next_state <= #1 m1_tx_force_clk_l;
+ end
+
+ m1_tx_first_wait_clk_h :
+ begin
+ enable_timer_5usec <= #1 1;
+ ps2_data_hi_z <= #1 0; // Start bit.
+ if (~ps2_clk_s && timer_5usec_done)
+ m1_next_state <= #1 m1_tx_clk_l;
+ else
+ m1_next_state <= #1 m1_tx_first_wait_clk_h;
+ end
+
+ // This state must be included because the device might possibly
+ // delay for up to 10 milliseconds before beginning its clock pulses.
+ // During that waiting time, we cannot drive the data (q[0]) because it
+ // is possibly 1, which would cause the keyboard to abort its receive
+ // and the expected clocks would then never be generated.
+ m1_tx_first_wait_clk_l :
+ begin
+ ps2_data_hi_z <= #1 0;
+ if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
+ else m1_next_state <= #1 m1_tx_first_wait_clk_l;
+ end
+
+ m1_tx_wait_clk_h :
+ begin
+ enable_timer_5usec <= #1 1;
+ ps2_data_hi_z <= #1 q[0];
+ if (ps2_clk_s && timer_5usec_done)
+ m1_next_state <= #1 m1_tx_rising_edge_marker;
+ else
+ m1_next_state <= #1 m1_tx_wait_clk_h;
+ end
+
+ m1_tx_rising_edge_marker :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ m1_next_state <= #1 m1_tx_clk_h;
+ end
+
+ m1_tx_clk_h :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ if (tx_shifting_done) m1_next_state <= #1 m1_tx_wait_keyboard_ack;
+ else if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
+ else m1_next_state <= #1 m1_tx_clk_h;
+ end
+
+ m1_tx_clk_l :
+ begin
+ ps2_data_hi_z <= #1 q[0];
+ if (ps2_clk_s) m1_next_state <= #1 m1_tx_wait_clk_h;
+ else m1_next_state <= #1 m1_tx_clk_l;
+ end
+
+ m1_tx_wait_keyboard_ack :
+ begin
+ if (~ps2_clk_s && ps2_data_s)
+ m1_next_state <= #1 m1_tx_error_no_keyboard_ack;
+ else if (~ps2_clk_s && ~ps2_data_s)
+ m1_next_state <= #1 m1_tx_done_recovery;
+ else m1_next_state <= #1 m1_tx_wait_keyboard_ack;
+ end
+
+ m1_tx_done_recovery :
+ begin
+ if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
+ else m1_next_state <= #1 m1_tx_done_recovery;
+ end
+
+ m1_tx_error_no_keyboard_ack :
+ begin
+ tx_error_no_keyboard_ack <= #1 1;
+ if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
+ else m1_next_state <= #1 m1_tx_error_no_keyboard_ack;
+ end
+
+ default : m1_next_state <= #1 m1_rx_clk_h;
+ endcase
+end
+
+// State register
+always @(posedge clk or posedge reset)
+begin : m2_state_register
+ if (reset) m2_state <= #1 m2_rx_data_ready_ack;
+ else m2_state <= #1 m2_next_state;
+end
+
+// State transition logic
+always @(m2_state or rx_output_strobe or rx_read)
+begin : m2_state_logic
+ case (m2_state)
+ m2_rx_data_ready_ack:
+ begin
+ rx_data_ready <= #1 1'b0;
+ if (rx_output_strobe) m2_next_state <= #1 m2_rx_data_ready;
+ else m2_next_state <= #1 m2_rx_data_ready_ack;
+ end
+ m2_rx_data_ready:
+ begin
+ rx_data_ready <= #1 1'b1;
+ if (rx_read) m2_next_state <= #1 m2_rx_data_ready_ack;
+ else m2_next_state <= #1 m2_rx_data_ready;
+ end
+ default : m2_next_state <= #1 m2_rx_data_ready_ack;
+ endcase
+end
+
+// This is the bit counter
+always @(posedge clk or posedge reset)
+begin
+ if ( reset) bit_count <= #1 0;
+ else if ( rx_shifting_done || (m1_state == m1_tx_wait_keyboard_ack) // After tx is done.
+ ) bit_count <= #1 0; // normal reset
+ else if (timer_60usec_done
+ && (m1_state == m1_rx_clk_h)
+ && (ps2_clk_s)
+ ) bit_count <= #1 0; // rx watchdog timer reset
+ else if ( (m1_state == m1_rx_falling_edge_marker) // increment for rx
+ ||(m1_state == m1_tx_rising_edge_marker) // increment for tx
+ )
+ bit_count <= #1 bit_count + 1;
+end
+// This signal is high for one clock at the end of the timer count.
+assign rx_shifting_done = (bit_count == `TOTAL_BITS);
+assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
+
+// This is the signal which enables loading of the shift register.
+// It also indicates "ack" to the device writing to the transmitter.
+assign tx_write_ack_o = ( (tx_write && (m1_state == m1_rx_clk_h))
+ ||(tx_write && (m1_state == m1_rx_clk_l))
+ );
+
+// This is the ODD parity bit for the transmitted word.
+assign tx_parity_bit = ~^tx_data;
+
+// This is the shift register
+always @(posedge clk or posedge reset)
+begin
+ if (reset) q <= #1 0;
+ else if (tx_write_ack_o) q <= #1 {1'b1,tx_parity_bit,tx_data,1'b0};
+ else if ( (m1_state == m1_rx_falling_edge_marker)
+ ||(m1_state == m1_tx_rising_edge_marker) )
+ q <= #1 {ps2_data_s,q[`TOTAL_BITS-1:1]};
+end
+
+// This is the 60usec timer counter
+always @(posedge clk)
+begin
+ if (~enable_timer_60usec) timer_60usec_count <= #1 0;
+ else if ( timer_done && !timer_60usec_done)
+ timer_60usec_count<= #1 timer_60usec_count +1;
+ end
+assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP ));
+
+
+
+always @(posedge clk or posedge reset)
+if (reset) timer_5usec <= #1 1;
+else if (!enable_timer_60usec) timer_5usec <= #1 1;
+else if (timer_5usec == devide_reg_i)
+ begin
+ timer_5usec <= #1 1;
+ timer_done <= #1 1;
+ end
+else
+ begin
+ timer_5usec<= #1 timer_5usec +1;
+ timer_done <= #1 0;
+ end
+
+// This is the 5usec timer counter
+always @(posedge clk)
+begin
+ if (~enable_timer_5usec) timer_5usec_count <= #1 0;
+ else if (~timer_5usec_done) timer_5usec_count <= #1 timer_5usec_count + 1;
+end
+assign timer_5usec_done = (timer_5usec_count == devide_reg_i -1);
+
+
+// Create the signals which indicate special scan codes received.
+// These are the "unlatched versions."
+assign released = (q[8:1] == `RELEASE_CODE) && rx_shifting_done && translate ;
+
+// Store the special scan code status bits
+// Not the final output, but an intermediate storage place,
+// until the entire set of output data can be assembled.
+always @(posedge clk or posedge reset)
+begin
+ if (reset) hold_released <= #1 0;
+ else if (rx_output_event)
+ begin
+ hold_released <= #1 0;
+ end
+ else
+ begin
+ if (rx_shifting_done && released) hold_released <= #1 1;
+ end
+end
+
+// Output the special scan code flags, the scan code and the ascii
+always @(posedge clk or posedge reset)
+begin
+ if (reset)
+ begin
+ rx_released <= #1 0;
+ rx_scan_code <= #1 0;
+ end
+ else if (rx_output_strobe)
+ begin
+ rx_released <= #1 hold_released;
+ rx_scan_code <= #1 q[8:1];
+ end
+end
+
+// Store the final rx output data only when all extend and release codes
+// are received and the next (actual key) scan code is also ready.
+// (the presence of rx_extended or rx_released refers to the
+// the current latest scan code received, not the previously latched flags.)
+assign rx_output_event = (rx_shifting_done
+ && ~released
+ );
+
+assign rx_output_strobe = (rx_shifting_done
+ && ~released
+ );
+
+endmodule
+
+//`undefine TOTAL_BITS
+//`undefine EXTEND_CODE
+//`undefine RELEASE_CODE
+//`undefine LEFT_SHIFT
+//`undefine RIGHT_SHIFT
+
tags/rel_13/rtl/verilog/ps2_keyboard.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/rtl/verilog/ps2_defines.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_defines.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_defines.v (revision 42)
@@ -0,0 +1,78 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_defines.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.4 2003/07/01 12:34:03 mihad
+// Added an option to use constant values instead of RAM
+// in the translation table.
+//
+// Revision 1.3 2002/04/09 13:21:15 mihad
+// Added mouse interface and everything for its handling, cleaned up some unused code
+//
+// Revision 1.2 2002/02/18 16:33:08 mihad
+// Changed defines for simulation to work without xilinx primitives
+//
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+//`define PS2_RAMB4
+`define PS2_CONSTANTS_ROM
+
+`define PS2_TRANSLATION_TABLE_31_0 256'h5b03111e1f2c71665a02101d702a386559290f3e40424464583c3b3d3f4143ff
+`define PS2_TRANSLATION_TABLE_63_32 256'h5f0908162432726a5e071522233031695d061314212f39685c040512202d2e67
+`define PS2_TRANSLATION_TABLE_95_64 256'h76632b751b1c363a6e620d1a7428736d610c19272635346c600a0b181725336b
+`define PS2_TRANSLATION_TABLE_127_96 256'h544649374a514e574501484d4c5053526f7f7e474b7d4f7c7b0e7a7978775655
+`define PS2_TRANSLATION_TABLE_159_128 256'h9f9e9d9c9b9a999897969594939291908f8e8d8c8b8a89888786855441828180
+`define PS2_TRANSLATION_TABLE_191_160 256'hbfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0
+`define PS2_TRANSLATION_TABLE_223_192 256'hdfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0
+`define PS2_TRANSLATION_TABLE_255_224 256'hfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0
+
+`define PS2_TIMER_60USEC_VALUE_PP 12 // Number of sys_clks for 60usec.
+`define PS2_TIMER_60USEC_BITS_PP 4 // Number of bits needed for timer
+`define PS2_TIMER_5USEC_VALUE_PP 500 // Number of sys_clks for debounce
+`define PS2_TIMER_5USEC_BITS_PP 16 // Number of bits needed for timer
+
+//`define PS2_AUX
tags/rel_13/rtl/verilog/ps2_defines.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/rtl/verilog/ps2_top.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_top.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_top.v (revision 42)
@@ -0,0 +1,305 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_top.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.5 2003/06/30 15:29:27 simons
+// Error fixed again.
+//
+// Revision 1.4 2003/06/30 15:25:45 simons
+// Error fixed.
+//
+// Revision 1.3 2003/05/28 16:27:09 simons
+// Change the address width.
+//
+// Revision 1.2 2002/04/09 13:21:15 mihad
+// Added mouse interface and everything for its handling, cleaned up some unused code
+//
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+`include "ps2_defines.v"
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+module ps2_top
+(
+ wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i,
+ wb_sel_i,
+ wb_adr_i,
+ wb_dat_i,
+ wb_dat_o,
+ wb_ack_o,
+
+ wb_int_o,
+
+ ps2_kbd_clk_pad_i,
+ ps2_kbd_data_pad_i,
+ ps2_kbd_clk_pad_o,
+ ps2_kbd_data_pad_o,
+ ps2_kbd_clk_pad_oe_o,
+ ps2_kbd_data_pad_oe_o
+ `ifdef PS2_AUX
+ ,
+ wb_intb_o,
+
+ ps2_aux_clk_pad_i,
+ ps2_aux_data_pad_i,
+ ps2_aux_clk_pad_o,
+ ps2_aux_data_pad_o,
+ ps2_aux_clk_pad_oe_o,
+ ps2_aux_data_pad_oe_o
+ `endif
+) ;
+
+input wb_clk_i,
+ wb_rst_i,
+ wb_cyc_i,
+ wb_stb_i,
+ wb_we_i ;
+
+input [3:0] wb_sel_i ;
+
+input [3:0] wb_adr_i ;
+input [31:0] wb_dat_i ;
+
+output [31:0] wb_dat_o ;
+
+output wb_ack_o ;
+
+output wb_int_o ;
+
+input ps2_kbd_clk_pad_i,
+ ps2_kbd_data_pad_i ;
+
+output ps2_kbd_clk_pad_o,
+ ps2_kbd_data_pad_o,
+ ps2_kbd_clk_pad_oe_o,
+ ps2_kbd_data_pad_oe_o ;
+
+`ifdef PS2_AUX
+output wb_intb_o ;
+input ps2_aux_clk_pad_i,
+ ps2_aux_data_pad_i ;
+
+output ps2_aux_clk_pad_o,
+ ps2_aux_data_pad_o,
+ ps2_aux_clk_pad_oe_o,
+ ps2_aux_data_pad_oe_o ;
+
+assign ps2_aux_clk_pad_o = 1'b0 ;
+assign ps2_aux_data_pad_o = 1'b0 ;
+`endif
+
+wire rx_released,
+ rx_kbd_data_ready,
+ rx_translated_data_ready,
+ rx_kbd_read_wb,
+ rx_kbd_read_tt,
+ tx_kbd_write,
+ tx_kbd_write_ack,
+ tx_error_no_keyboard_ack,
+ ps2_ctrl_kbd_data_en_,
+ ps2_ctrl_kbd_clk_en_,
+ ps2_ctrl_kbd_clk,
+ inhibit_kbd_if ;
+
+wire [15:0] devide_reg;
+
+wire [7:0] rx_scan_code,
+ rx_translated_scan_code,
+ tx_kbd_data ;
+
+assign ps2_kbd_clk_pad_o = 1'b0 ;
+assign ps2_kbd_data_pad_o = 1'b0 ;
+
+ps2_io_ctrl i_ps2_io_ctrl_keyboard
+(
+ .clk_i (wb_clk_i),
+ .rst_i (wb_rst_i),
+ .ps2_ctrl_clk_en_i_ (ps2_ctrl_kbd_clk_en_),
+ .ps2_ctrl_data_en_i_ (ps2_ctrl_kbd_data_en_),
+ .ps2_clk_pad_i (ps2_kbd_clk_pad_i),
+ .ps2_clk_pad_oe_o (ps2_kbd_clk_pad_oe_o),
+ .ps2_data_pad_oe_o (ps2_kbd_data_pad_oe_o),
+ .inhibit_if_i (inhibit_kbd_if),
+ .ps2_ctrl_clk_o (ps2_ctrl_kbd_clk)
+);
+
+`ifdef PS2_AUX
+wire rx_aux_data_ready,
+ rx_aux_read,
+ tx_aux_write,
+ tx_aux_write_ack,
+ tx_error_no_aux_ack,
+ ps2_ctrl_aux_data_en_,
+ ps2_ctrl_aux_clk_en_,
+ ps2_ctrl_aux_clk,
+ inhibit_aux_if ;
+
+wire [7:0] rx_aux_data,
+ tx_aux_data ;
+
+ps2_io_ctrl i_ps2_io_ctrl_auxiliary
+(
+ .clk_i (wb_clk_i),
+ .rst_i (wb_rst_i),
+ .ps2_ctrl_clk_en_i_ (ps2_ctrl_aux_clk_en_),
+ .ps2_ctrl_data_en_i_ (ps2_ctrl_aux_data_en_),
+ .ps2_clk_pad_i (ps2_aux_clk_pad_i),
+ .ps2_clk_pad_oe_o (ps2_aux_clk_pad_oe_o),
+ .ps2_data_pad_oe_o (ps2_aux_data_pad_oe_o),
+ .inhibit_if_i (inhibit_aux_if),
+ .ps2_ctrl_clk_o (ps2_ctrl_aux_clk)
+);
+
+ps2_mouse #(`PS2_TIMER_60USEC_VALUE_PP, `PS2_TIMER_60USEC_BITS_PP, `PS2_TIMER_5USEC_VALUE_PP, `PS2_TIMER_5USEC_BITS_PP)
+i_ps2_mouse
+(
+ .clk (wb_clk_i),
+ .reset (wb_rst_i),
+ .ps2_clk_en_o_ (ps2_ctrl_aux_clk_en_),
+ .ps2_data_en_o_ (ps2_ctrl_aux_data_en_),
+ .ps2_clk_i (ps2_ctrl_aux_clk),
+ .ps2_data_i (ps2_aux_data_pad_i),
+ .rx_scan_code (rx_aux_data),
+ .rx_data_ready (rx_aux_data_ready),
+ .rx_read (rx_aux_read),
+ .tx_data (tx_aux_data),
+ .tx_write (tx_aux_write),
+ .tx_write_ack_o (tx_aux_write_ack),
+ .tx_error_no_ack (tx_error_no_aux_ack),
+ .devide_reg_i (devide_reg)
+);
+
+`endif
+
+ps2_keyboard #(`PS2_TIMER_60USEC_VALUE_PP, `PS2_TIMER_60USEC_BITS_PP, `PS2_TIMER_5USEC_VALUE_PP, `PS2_TIMER_5USEC_BITS_PP)
+i_ps2_keyboard
+(
+ .clk (wb_clk_i),
+ .reset (wb_rst_i),
+ .ps2_clk_en_o_ (ps2_ctrl_kbd_clk_en_),
+ .ps2_data_en_o_ (ps2_ctrl_kbd_data_en_),
+ .ps2_clk_i (ps2_ctrl_kbd_clk),
+ .ps2_data_i (ps2_kbd_data_pad_i),
+ .rx_released (rx_released),
+ .rx_scan_code (rx_scan_code),
+ .rx_data_ready (rx_kbd_data_ready),
+ .rx_read (rx_kbd_read_tt),
+ .tx_data (tx_kbd_data),
+ .tx_write (tx_kbd_write),
+ .tx_write_ack_o (tx_kbd_write_ack),
+ .tx_error_no_keyboard_ack (tx_error_no_keyboard_ack),
+ .translate (translate),
+ .devide_reg_i (devide_reg)
+);
+
+ps2_wb_if i_ps2_wb_if
+(
+ .wb_clk_i (wb_clk_i),
+ .wb_rst_i (wb_rst_i),
+ .wb_cyc_i (wb_cyc_i),
+ .wb_stb_i (wb_stb_i),
+ .wb_we_i (wb_we_i),
+ .wb_sel_i (wb_sel_i),
+ .wb_adr_i (wb_adr_i),
+ .wb_dat_i (wb_dat_i),
+ .wb_dat_o (wb_dat_o),
+ .wb_ack_o (wb_ack_o),
+
+ .wb_int_o (wb_int_o),
+
+ .devide_reg_o (devide_reg),
+
+ .rx_scancode_i (rx_translated_scan_code),
+ .rx_kbd_data_ready_i (rx_translated_data_ready),
+ .rx_kbd_read_o (rx_kbd_read_wb),
+ .tx_kbd_data_o (tx_kbd_data),
+ .tx_kbd_write_o (tx_kbd_write),
+ .tx_kbd_write_ack_i (tx_kbd_write_ack),
+ .translate_o (translate),
+ .ps2_kbd_clk_i (ps2_kbd_clk_pad_i),
+ .inhibit_kbd_if_o (inhibit_kbd_if)
+ `ifdef PS2_AUX
+ ,
+ .wb_intb_o (wb_intb_o),
+
+ .rx_aux_data_i (rx_aux_data),
+ .rx_aux_data_ready_i (rx_aux_data_ready),
+ .rx_aux_read_o (rx_aux_read),
+ .tx_aux_data_o (tx_aux_data),
+ .tx_aux_write_o (tx_aux_write),
+ .tx_aux_write_ack_i (tx_aux_write_ack),
+ .ps2_aux_clk_i (ps2_aux_clk_pad_i),
+ .inhibit_aux_if_o (inhibit_aux_if)
+ `endif
+) ;
+
+ps2_translation_table i_ps2_translation_table
+(
+ .reset_i (wb_rst_i),
+ .clock_i (wb_clk_i),
+ .translate_i (translate),
+ .code_i (rx_scan_code),
+ .code_o (rx_translated_scan_code),
+ .address_i (8'h00),
+ .data_i (8'h00),
+ .we_i (1'b0),
+ .re_i (1'b0),
+ .data_o (),
+ .rx_data_ready_i (rx_kbd_data_ready),
+ .rx_translated_data_ready_o (rx_translated_data_ready),
+ .rx_read_i (rx_kbd_read_wb),
+ .rx_read_o (rx_kbd_read_tt),
+ .rx_released_i (rx_released)
+) ;
+
+endmodule // ps2_top
Index: tags/rel_13/rtl/verilog/ps2_translation_table.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_translation_table.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_translation_table.v (revision 42)
@@ -0,0 +1,290 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_translation_table.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.3 2003/06/02 17:13:22 simons
+// resetall keyword removed. ifdef moved to a separated line.
+//
+// Revision 1.2 2002/04/09 13:21:15 mihad
+// Added mouse interface and everything for its handling, cleaned up some unused code
+//
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+`include "ps2_defines.v"
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+module ps2_translation_table
+(
+ reset_i,
+ clock_i,
+ translate_i,
+ code_i,
+ code_o,
+ address_i,
+ data_i,
+ we_i,
+ re_i,
+ data_o,
+ rx_data_ready_i,
+ rx_translated_data_ready_o,
+ rx_read_i,
+ rx_read_o,
+ rx_released_i
+) ;
+
+input reset_i,
+ clock_i,
+ translate_i ;
+
+input [7:0] code_i ;
+output [7:0] code_o ;
+input [7:0] address_i ;
+input [7:0] data_i ;
+input we_i,
+ re_i ;
+
+output [7:0] data_o ;
+
+input rx_data_ready_i,
+ rx_read_i ;
+
+output rx_translated_data_ready_o ;
+output rx_read_o ;
+
+input rx_released_i ;
+
+wire translation_table_write_enable = we_i && (!translate_i || !rx_data_ready_i) ;
+wire [7:0] translation_table_address = ((we_i || re_i) && (!rx_data_ready_i || !translate_i)) ? address_i : code_i ;
+wire translation_table_enable = we_i || re_i || (translate_i && rx_data_ready_i) ;
+
+reg rx_translated_data_ready ;
+always@(posedge clock_i or posedge reset_i)
+begin
+ if ( reset_i )
+ rx_translated_data_ready <= #1 1'b0 ;
+ else if ( rx_read_i || !translate_i )
+ rx_translated_data_ready <= #1 1'b0 ;
+ else
+ rx_translated_data_ready <= #1 rx_data_ready_i ;
+end
+
+`ifdef PS2_RAMB4
+ `define PS2_RAM_SELECTED
+
+ wire [7:0] ram_out ;
+ RAMB4_S8
+ `ifdef SIM
+ #("ignore",
+ `PS2_TRANSLATION_TABLE_31_0,
+ `PS2_TRANSLATION_TABLE_63_32,
+ `PS2_TRANSLATION_TABLE_95_64,
+ `PS2_TRANSLATION_TABLE_127_96,
+ `PS2_TRANSLATION_TABLE_159_128,
+ `PS2_TRANSLATION_TABLE_191_160,
+ `PS2_TRANSLATION_TABLE_223_192,
+ `PS2_TRANSLATION_TABLE_255_224)
+ `endif
+ ps2_ram
+ (
+ .DO (ram_out),
+ .ADDR ({1'b0, translation_table_address}),
+ .DI (data_i),
+ .EN (translation_table_enable),
+ .CLK (clock_i),
+ .WE (translation_table_write_enable),
+ .RST (reset_i)
+ ) ;
+
+`endif
+
+`ifdef PS2_CONSTANTS_ROM
+ `define PS2_RAM_SELECTED
+
+ reg [32 * 8 - 1:0] ps2_32byte_constant ;
+ reg [7:0] ram_out ;
+
+ always@(translation_table_address)
+ begin
+ case (translation_table_address[7:5])
+ 3'b000:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_31_0 ;
+ 3'b001:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_63_32 ;
+ 3'b010:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_95_64 ;
+ 3'b011:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_127_96 ;
+ 3'b100:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_159_128 ;
+ 3'b101:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_191_160 ;
+ 3'b110:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_223_192 ;
+ 3'b111:ps2_32byte_constant = `PS2_TRANSLATION_TABLE_255_224 ;
+ endcase
+ end
+
+ always@(posedge clock_i or posedge reset_i)
+ begin
+ if ( reset_i )
+ ram_out <= #1 8'h0 ;
+ else if ( translation_table_enable )
+ begin:get_dat_out
+ reg [7:0] bit_num ;
+
+ bit_num = translation_table_address[4:0] << 3 ;
+
+ repeat(8)
+ begin
+ ram_out[bit_num % 8] <= #1 ps2_32byte_constant[bit_num] ;
+ bit_num = bit_num + 1'b1 ;
+ end
+ end
+ end
+
+`endif
+
+`ifdef PS2_RAM_SELECTED
+`else
+ `define PS2_RAM_SELECTED
+
+ reg [7:0] ps2_ram [0:255] ;
+ reg [7:0] ram_out ;
+
+ always@(posedge clock_i or posedge reset_i)
+ begin
+ if ( reset_i )
+ ram_out <= #1 8'h0 ;
+ else if ( translation_table_enable )
+ ram_out <= #1 ps2_ram[translation_table_address] ;
+ end
+
+ always@(posedge clock_i)
+ begin
+ if ( translation_table_write_enable )
+ ps2_ram[translation_table_address] <= #1 data_i ;
+ end
+
+ // synopsys translate_off
+ initial
+ begin:ps2_ram_init
+ integer i ;
+ reg [255:0] temp_init_val ;
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_31_0 ;
+
+ for ( i = 0 ; i <= 31 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_63_32 ;
+
+ for ( i = 32 ; i <= 63 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_95_64 ;
+
+ for ( i = 64 ; i <= 95 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_127_96 ;
+
+ for ( i = 96 ; i <= 127 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_159_128 ;
+
+ for ( i = 128 ; i <= 159 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_191_160 ;
+
+ for ( i = 160 ; i <= 191 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_223_192 ;
+
+ for ( i = 192 ; i <= 223 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+
+ temp_init_val = `PS2_TRANSLATION_TABLE_255_224 ;
+
+ for ( i = 224 ; i <= 255 ; i = i + 1 )
+ begin
+ ps2_ram[i] = temp_init_val[7:0] ;
+ temp_init_val = temp_init_val >> 8 ;
+ end
+ end
+
+ // synopsys translate_on
+
+`endif
+
+assign data_o = ram_out ;
+assign code_o = translate_i ? {(rx_released_i | ram_out[7]), ram_out[6:0]} : code_i ;
+assign rx_translated_data_ready_o = translate_i ? rx_translated_data_ready : rx_data_ready_i ;
+assign rx_read_o = rx_read_i ;
+
+`undef PS2_RAM_SELECTED
+
+endmodule //ps2_translation_table
Index: tags/rel_13/rtl/verilog/ps2_io_ctrl.v
===================================================================
--- tags/rel_13/rtl/verilog/ps2_io_ctrl.v (nonexistent)
+++ tags/rel_13/rtl/verilog/ps2_io_ctrl.v (revision 42)
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ps2_io_ctrl.v ////
+//// ////
+//// This file is part of the "ps2" project ////
+//// http://www.opencores.org/cores/ps2/ ////
+//// ////
+//// Author(s): ////
+//// - mihad@opencores.org ////
+//// - Miha Dolenc ////
+//// ////
+//// All additional information is avaliable in the README.txt ////
+//// file. ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// CVS Revision History
+//
+// $Log: not supported by cvs2svn $
+// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
+// Initial project import - working
+//
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+module ps2_io_ctrl
+(
+ clk_i,
+ rst_i,
+ ps2_ctrl_clk_en_i_,
+ ps2_ctrl_data_en_i_,
+ ps2_clk_pad_i,
+ ps2_clk_pad_oe_o,
+ ps2_data_pad_oe_o,
+ inhibit_if_i,
+ ps2_ctrl_clk_o
+);
+
+input clk_i,
+ rst_i,
+ ps2_ctrl_clk_en_i_,
+ ps2_ctrl_data_en_i_,
+ ps2_clk_pad_i,
+ inhibit_if_i ;
+
+output ps2_clk_pad_oe_o,
+ ps2_data_pad_oe_o,
+ ps2_ctrl_clk_o ;
+
+reg ps2_clk_pad_oe_o,
+ ps2_data_pad_oe_o ;
+
+always@(posedge clk_i or posedge rst_i)
+begin
+ if ( rst_i )
+ begin
+ ps2_clk_pad_oe_o <= #1 1'b0 ;
+ ps2_data_pad_oe_o <= #1 1'b0 ;
+ end
+ else
+ begin
+ ps2_clk_pad_oe_o <= #1 !ps2_ctrl_clk_en_i_ || inhibit_if_i ;
+ ps2_data_pad_oe_o <= #1 !ps2_ctrl_data_en_i_ ;
+ end
+end
+
+reg inhibit_if_previous ;
+always@(posedge clk_i or posedge rst_i)
+begin
+ if ( rst_i )
+ inhibit_if_previous <= #1 1'b1 ;
+ else
+ inhibit_if_previous <= #1 inhibit_if_i ;
+end
+
+assign ps2_ctrl_clk_o = ps2_clk_pad_i || ps2_clk_pad_oe_o && inhibit_if_previous ;
+endmodule // ps2_io_ctrl
Index: tags/rel_13/rtl/verilog/timescale.v
===================================================================
--- tags/rel_13/rtl/verilog/timescale.v (nonexistent)
+++ tags/rel_13/rtl/verilog/timescale.v (revision 42)
@@ -0,0 +1 @@
+`timescale 1ns/1ps
\ No newline at end of file
Index: tags/rel_13/syn/xilinx/constraints/ps2.ucf
===================================================================
--- tags/rel_13/syn/xilinx/constraints/ps2.ucf (nonexistent)
+++ tags/rel_13/syn/xilinx/constraints/ps2.ucf (revision 42)
@@ -0,0 +1,8 @@
+INST *ps2_ram INIT_00 = 5b03111e1f2c71665a02101d702a386559290f3e40424464583c3b3d3f4143ff ;
+INST *ps2_ram INIT_01 = 5f0908162432726a5e071522233031695d061314212f39685c040512202d2e67 ;
+INST *ps2_ram INIT_02 = 76632b751b1c363a6e620d1a7428736d610c19272635346c600a0b181725336b ;
+INST *ps2_ram INIT_03 = 544649374a514e574501484d4c5053526f7f7e474b7d4f7c7b0e7a7978775655 ;
+INST *ps2_ram INIT_04 = 9f9e9d9c9b9a999897969594939291908f8e8d8c8b8a89888786855441828180 ;
+INST *ps2_ram INIT_05 = bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0 ;
+INST *ps2_ram INIT_06 = dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0 ;
+INST *ps2_ram INIT_07 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 ;
tags/rel_13/syn/xilinx/constraints/ps2.ucf
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/syn/xilinx/constraints/ps2.sdc
===================================================================
--- tags/rel_13/syn/xilinx/constraints/ps2.sdc (nonexistent)
+++ tags/rel_13/syn/xilinx/constraints/ps2.sdc (revision 42)
@@ -0,0 +1,33 @@
+# Synplicity, Inc. constraint file
+# G:\ps2\mihad\ps2\syn\xilinx\constraints\ps2.sdc
+# Written on Mon Feb 18 14:17:46 2002
+# by Synplify Pro, 7.0 Beta3 Scope Editor
+
+#
+# Clocks
+#
+
+#
+# Inputs/Outputs
+#
+
+#
+# Registers
+#
+
+#
+# Multicycle Path
+#
+
+#
+# False Path
+#
+
+#
+# Attributes
+#
+define_global_attribute syn_netlist_hierarchy {0}
+
+#
+# Other Constraints
+#
tags/rel_13/syn/xilinx/constraints/ps2.sdc
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/rel_13/misc/scancode_translation_values
===================================================================
--- tags/rel_13/misc/scancode_translation_values (nonexistent)
+++ tags/rel_13/misc/scancode_translation_values (revision 42)
@@ -0,0 +1,17 @@
+Values are listed from 0 - 255
+0xff,0x43,0x41,0x3f,0x3d,0x3b,0x3c,0x58,0x64,0x44,0x42,0x40,0x3e,0x0f,0x29,0x59,
+0x65,0x38,0x2a,0x70,0x1d,0x10,0x02,0x5a,0x66,0x71,0x2c,0x1f,0x1e,0x11,0x03,0x5b,
+0x67,0x2e,0x2d,0x20,0x12,0x05,0x04,0x5c,0x68,0x39,0x2f,0x21,0x14,0x13,0x06,0x5d,
+0x69,0x31,0x30,0x23,0x22,0x15,0x07,0x5e,0x6a,0x72,0x32,0x24,0x16,0x08,0x09,0x5f,
+0x6b,0x33,0x25,0x17,0x18,0x0b,0x0a,0x60,0x6c,0x34,0x35,0x26,0x27,0x19,0x0c,0x61,
+0x6d,0x73,0x28,0x74,0x1a,0x0d,0x62,0x6e,0x3a,0x36,0x1c,0x1b,0x75,0x2b,0x63,0x76,
+0x55,0x56,0x77,0x78,0x79,0x7a,0x0e,0x7b,0x7c,0x4f,0x7d,0x4b,0x47,0x7e,0x7f,0x6f,
+0x52,0x53,0x50,0x4c,0x4d,0x48,0x01,0x45,0x57,0x4e,0x51,0x4a,0x37,0x49,0x46,0x54,
+0x80,0x81,0x82,0x41,0x54,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
\ No newline at end of file
tags/rel_13/misc/scancode_translation_values
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property