1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-04-21 12:27:27 +03:00

Adding PS2, capacitive keyboard examples

This commit is contained in:
carlos
2010-11-30 19:26:56 -05:00
parent 2efe106cf3
commit 62d0edf217
275 changed files with 1696660 additions and 23991 deletions

45
PS2_INTERFACE/logic/kb_ps2.v Executable file
View File

@@ -0,0 +1,45 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 12:22:40 10/07/2010
// Design Name:
// Module Name: kb_ps2
// Project Name: keyboard
// Target Devices:
// Tool versions:
// Description: controlador de teclado
//
// Dependencies: ps2_rx, ps2_tx
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module kb_ps2(
input wire clk, reset,
input wire we_ps2,
inout wire ps2_data, ps2_clk,
input wire [7:0] din,
output wire rx_done, tx_done,
output wire [7:0] dout
);
// signal declaration
wire tx_idle;
// instantiate ps2 receiver
ps2_rx ps2_rx_1
(.clk(clk), .reset(reset), .rx_en(tx_idle),
.ps2_data(ps2_data), .ps2_clk(ps2_clk),
.rx_done(rx_done), .dout(dout));
// instantiate ps2 transmitter
ps2_tx ps2_tx_1
(.clk(clk), .reset(reset), .we_ps2(we_ps2),
.din(din), .ps2_data(ps2_data), .ps2_clk(ps2_clk),
.tx_idle(tx_idle), .tx_done(tx_done));
endmodule

View File

@@ -0,0 +1,38 @@
NET clk LOC = "P38";
NET reset LOC = "P30";
NET led LOC = "P44";
NET irq_kb LOC = "P71";
#ADDRESS BUS
NET "addr<12>" LOC = "P90";
NET "addr<11>" LOC = "P91";
NET "addr<10>" LOC = "P85";
NET "addr<9>" LOC = "P92";
NET "addr<8>" LOC = "P94";
NET "addr<7>" LOC = "P95";
NET "addr<6>" LOC = "P98";
NET "addr<5>" LOC = "P3";
NET "addr<4>" LOC = "P2";
NET "addr<3>" LOC = "P78";
NET "addr<2>" LOC = "P79";
NET "addr<1>" LOC = "P83";
NET "addr<0>" LOC = "P84";
#DATA BUS
NET "data<7>" LOC = "P4";
NET "data<6>" LOC = "P5";
NET "data<5>" LOC = "P9";
NET "data<4>" LOC = "P10";
NET "data<3>" LOC = "P11";
NET "data<2>" LOC = "P12";
NET "data<1>" LOC = "P15";
NET "data<0>" LOC = "P16";
#CONTROL BUS
NET "nwe" LOC = "P88";
NET "noe" LOC = "P86";
NET "ncs" LOC = "P69";
#PS/2
NET ps2_data LOC = "P65";#"P68";
NET ps2_clk LOC = "P62";#"P63";

View File

@@ -0,0 +1,80 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: UNAL
// Engineer: Ari Bejarano
//
// Create Date: 16:28:50 09/30/2010
// Design Name: ps2_interface
// Module Name: ps2_interface
// Project Name: ps2_interface
// Target Devices:
// Tool versions: 2.0
// Description: ¬¬
//
// Dependencies: sync.v, writePulseGenerator.v, kb_ps2
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ps2_interface(clk, data, addr, nwe, ncs, noe, reset, ps2_data, ps2_clk, irq_kb, led);
parameter N = 13, M = 8;// M # de lineas de datos, N # de lineas de dirección
input clk, nwe, ncs, noe, reset;
input [N-1:0] addr;
inout [M-1:0] data;
inout ps2_clk;
inout ps2_data;
output irq_kb;
output led;
wire sncs;
wire snwe;
wire [N-1:0] buffer_addr;
wire [M-1:0] rdBus;
wire [M-1:0] wdBus;
wire we;
wire rx_done;
assign led = ps2_clk;
sync # (.N(13), .M(8))// M # de lineas de datos, N # de lineas de dirección
sync_U1(.clk(clk),
.data(data),
.addr(addr),
.nwe(nwe),
.ncs(ncs),
.noe(noe),
.rdBus(rdBus),
.sncs(sncs),
.snwe(snwe),
.buffer_addr(buffer_addr),
.buffer_data(wdBus));
writePulseGenerator writePulseGenerator_U2 (.clk(clk),
.snwe(snwe),
.sncs(sncs),
.reset(reset),
.we(we));
kb_ps2 kb_ps2_U3(.clk(~clk),
.reset(~reset),
.we_ps2(we),
.ps2_data(ps2_data),
.ps2_clk(ps2_clk),
.din(wdBus),
.rx_done(rx_done),
.tx_done(),
.dout(rdBus));
pulse_expander pulse_expander_U4(
.clk(clk),
.reset(~reset),
.pulse_in(rx_done),
.pulse_out(irq_kb)
);
endmodule

View File

@@ -0,0 +1,3 @@
iverilog -o ps2_interface_TF ps2_interface_TF.v ps2_interface.v kb_ps2.v ps2_rx.v ps2_tx.v pulse_expander.v sync.v writePulseGenerator.v
vvp ps2_interface_TF
gtkwave ps2_interface_TF.vcd

View File

@@ -0,0 +1,251 @@
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:48:20 10/15/2010
// Design Name: ps2_interface
// Module Name: /home/ari/Xilinx_Projects/ps2_interface/ps2_interface_TF.v
// Project Name: ps2_interface
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: ps2_interface
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module ps2_interface_TF;
// Inputs
reg clk;
reg [12:0] addr;
reg nwe;
reg ncs;
reg noe;
reg reset;
// Outputs
wire irq_kb;
wire led;
// Bidirs
wire [7:0] data;
wire ps2_data;
wire ps2_clk;
reg ps2_datar;
reg ps2_clkr;
reg [7:0] datar;
// Instantiate the Unit Under Test (UUT)
ps2_interface uut (
.clk(clk),
.data(data),
.addr(addr),
.nwe(nwe),
.ncs(ncs),
.noe(noe),
.reset(reset),
.ps2_data(ps2_data),
.ps2_clk(ps2_clk),
.irq_kb(irq_kb),
.led(led)
);
initial begin
// Initialize Inputs
clk = 0;
addr = 0;
nwe = 1;
ncs = 0;
noe = 1;
reset = 1;
ps2_datar = 1;
ps2_clkr = 1;
datar = 8'bz;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
reset = 0;
#100;
reset = 1;
#100;
//start
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data1
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data2
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data3
#25000;
ps2_datar=1;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data4
#25000;
ps2_datar=1;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data5
#25000;
ps2_datar=1;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data6
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data7
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//data8
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//parity
#25000;
ps2_datar=0;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
//stop
#25000;
ps2_datar=1;
#25000;
ps2_clkr=0;
#50000;
ps2_clkr=1;
#50000;
datar=8'b01011010;
noe = 0;
nwe = 0;
ps2_datar=1'bz;
ps2_clkr=1'bz;
#400
nwe = 1;
#80000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
#50000
ps2_clkr=0;
#50000
ps2_clkr=1;
end
always
#10 clk=!clk;
initial begin
$dumpfile ("ps2_interface_TF.vcd");
$dumpvars;
end
initial begin
$display("\t\ttime,\tclk,\tdata,\taddr,\tnwe,\tncs,\tnoe,\treset,\tps2_data,\tps2_clk,\tirq_kb");
$monitor("%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d",
$time,clk,data,addr,nwe,ncs,noe,reset,ps2_data,ps2_clk,irq_kb);
end
initial
#3000000 $finish;
assign ps2_clk=ps2_clkr;
assign ps2_data=ps2_datar;
assign data=datar;
endmodule

File diff suppressed because it is too large Load Diff

98
PS2_INTERFACE/logic/ps2_rx.v Executable file
View File

@@ -0,0 +1,98 @@
`timescale 1ns / 1ps
module ps2_rx(
input wire clk, reset,
input wire ps2_data, ps2_clk, rx_en,
output reg rx_done,
output wire [7:0] dout
);
//signal declaration
reg [1:0] state_reg, state_next;
reg [7:0] filter_reg;
wire [7:0] filter_next;
reg f_ps2c_reg;
wire f_ps2c_next;
reg [3:0] n_reg, n_next;
reg [10:0] b_reg, b_next;
wire fall_edge;
//====================================================
// falling - edge generation for ps2_clk
//====================================================
always @(posedge clk, posedge reset)
if (reset)
begin
filter_reg <= 0;
f_ps2c_reg <= 0;
end
else
begin
filter_reg <= filter_next;
f_ps2c_reg <= f_ps2c_next;
end
assign filter_next = {ps2_clk, filter_reg[7:1]};
assign f_ps2c_next = (filter_reg==8'b11111111) ? 1'b1 :
(filter_reg==8'b00000000) ? 1'b0 :
f_ps2c_reg;
assign fall_edge = f_ps2c_reg & ~f_ps2c_next;
//==============================================================
// FSM
//==============================================================
// state & data registers
always @(posedge clk, posedge reset)
if(reset)
begin
state_reg <= 1;
n_reg <= 0;
b_reg <= 0;
end
else
begin
state_reg <= state_next;
n_reg <= n_next;
b_reg <= b_next;
end
// next state logic
always @(*)
begin
state_next = state_reg;
n_next = n_reg;
b_next = b_reg;
rx_done = 1'b0;
case(state_reg)
1:
if(fall_edge & rx_en)
begin
//shift in start bit
b_next = {ps2_data, b_reg[10:1]};
n_next = 4'b1001;
state_next = 2;
end
2: // 8 data + 1 parity + 1 stop
begin
if(fall_edge)
begin
b_next = {ps2_data, b_reg[10:1]};
if(n_reg==0)
state_next = 3;
else
n_next = n_reg-1;
end
end
3: // 1 extra clock to complete the last shift
begin
state_next = 1;
rx_done = 1'b1;
end
default: state_next = 1;
endcase
end
//output
assign dout = b_reg[8:1]; //data bits
endmodule

165
PS2_INTERFACE/logic/ps2_tx.v Executable file
View File

@@ -0,0 +1,165 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 11:52:20 10/07/2010
// Design Name:
// Module Name: ps2_tx
// Project Name: keyboard
// Target Devices:
// Tool versions:
// Description: transmisor de teclado ps2
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ps2_tx
(
input wire clk, reset,
input wire we_ps2,
input wire [7:0] din,
inout wire ps2_data, ps2_clk,
output reg tx_idle, tx_done
);
// symbolic state declaration
localparam [2:0]
idle = 3'b000,
rts = 3'b001,
start = 3'b010,
data = 3'b011,
stop = 3'b100;
// signal declaration
reg [2:0] state_reg, state_next;
reg [7:0] filter_reg;
wire [7:0] filter_next;
reg f_ps2c_reg;
wire f_ps2c_next;
reg [3:0] n_reg, n_next;
reg [8:0] b_reg, b_next;
reg [12:0] c_reg, c_next;
wire par, fall_edge;
reg ps2c_out, ps2d_out;
reg tri_c, tri_d;
//=================================================
// falling-edge generation for ps2_clk
//=================================================
always @(posedge clk, posedge reset)
if (reset)
begin
filter_reg <= 0;
f_ps2c_reg <= 0;
end
else
begin
filter_reg <= filter_next;
f_ps2c_reg <= f_ps2c_next;
end
assign filter_next = {ps2_clk, filter_reg[7:1]};
assign f_ps2c_next = (filter_reg==8'b11111111) ? 1'b1 :
(filter_reg==8'b00000000) ? 1'b0 :
f_ps2c_reg;
assign fall_edge = f_ps2c_reg & ~f_ps2c_next;
//=================================================
// FSM
//=================================================
// state & data registers
always @(posedge clk, posedge reset)
if (reset)
begin
state_reg <= idle;
c_reg <= 0;
n_reg <= 0;
b_reg <= 0;
end
else
begin
state_reg <= state_next;
c_reg <= c_next;
n_reg <= n_next;
b_reg <= b_next;
end
// odd parity bit
assign par = ~(^din);
// FSM next-state logic
always @*
begin
state_next = state_reg;
c_next = c_reg;
n_next = n_reg;
b_next = b_reg;
tx_done = 1'b0;
ps2c_out = 1'bz;
ps2d_out = 1'bz;
tri_c = 1'b0;
tri_d = 1'b0;
tx_idle = 1'b0;
case (state_reg)
idle:
begin
tx_idle = 1'b1;
if (we_ps2)
begin
b_next = {par, din};
c_next = 13'h1fff; // 2^13-1
state_next = rts;
end
end
rts: // request to send
begin
ps2c_out = 1'b0;
tri_c = 1'b1;
c_next = c_reg - 1;
if (c_reg==0)
state_next = start;
end
start: // assert start bit
begin
ps2d_out = 1'b0;
tri_d = 1'b1;
if (fall_edge)
begin
n_next = 4'h8;
state_next = data;
end
end
data: // 8 data + 1 parity
begin
ps2d_out = (b_reg[0])? 1'bz : 1'b0;
tri_d = 1'b1;
if (fall_edge)
begin
b_next = {1'b0, b_reg[8:1]};
if (n_reg == 0)
state_next = stop;
else
n_next = n_reg - 1;
end
end
stop: // assume floating high for ps2_data
if (fall_edge)
begin
state_next = idle;
tx_done = 1'b1;
end
endcase
end
// tri-state buffers
assign ps2_clk = (tri_c) ? ps2c_out : 1'bz;
assign ps2_data = (tri_d) ? ps2d_out : 1'bz;
endmodule

View File

@@ -0,0 +1,57 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: U.N
// Engineer: Ari Andrés Bejarano H.
//
// Create Date: 07:19:56 10/15/2010
// Design Name:
// Module Name: pulse_expander
// Project Name:
// Target Devices:
// Tool versions:
// Description: expande pulse_out = (pulse_in) + (num * pulses of clk)
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module pulse_expander(
input clk,
input reset,
input pulse_in,
output reg pulse_out
);
parameter num = 5000;
reg [24:0] cnt;
reg flag;
always@(posedge clk)begin
if(reset)
begin
cnt <= 0;
pulse_out <= 0;
flag <= 0;
end
else
if(pulse_in || flag)
if(cnt < num)
begin
cnt <= cnt+1;
pulse_out <= 1;
flag <= 1;
end
else
begin
cnt <= 0;
pulse_out <= 0;
flag <= 0;
end
end
endmodule

View File

@@ -0,0 +1,82 @@
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 08:01:22 10/15/2010
// Design Name: pulse_expander
// Module Name: /home/ari/Xilinx_Projects/keyboard/pulse_expander_TF.v
// Project Name: keyboard
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: pulse_expander
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module pulse_expander_TF;
// Inputs
reg clk;
reg reset;
reg pulse_in;
// Outputs
wire pulse_out;
// Instantiate the Unit Under Test (UUT)
pulse_expander uut (
.clk(clk),
.reset(reset),
.pulse_in(pulse_in),
.pulse_out(pulse_out)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
pulse_in = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
reset = 1;
#100;
reset = 0;
#100;
pulse_in = 1;
#20;
pulse_in = 0;
#400;
pulse_in = 1;
#20;
pulse_in = 0;
end
always
#10 clk=!clk;
initial begin
$dumpfile ("pulse_expander_TF.vcd");
$dumpvars;
end
initial begin
$display("\t\ttime,\tclk,\treset,\tpulse_in,\tpulse_out");
$monitor("%d,\t%b,\t%b,\t%b,\t%d",$time, clk,reset,pulse_in,pulse_out);
end
initial
#2000 $finish;
endmodule

31
PS2_INTERFACE/logic/sync.v Executable file
View File

@@ -0,0 +1,31 @@
`timescale 1ns / 1ps
module sync # (parameter N = 13, M = 8)
(input clk,
inout [M-1:0] data,
input [N-1:0] addr,
input nwe,
input ncs,
input noe,
input [M-1:0] rdBus,
output reg sncs,
output reg snwe,
output reg [N-1:0] buffer_addr,
output [M-1:0] buffer_data);
// interefaz signals assignments
wire T = ~noe | ncs;
assign data = T?8'bZ:rdBus;
assign buffer_data = data;
// synchronize assignment
always @(negedge clk)
begin
sncs <= ncs;
snwe <= nwe;
buffer_addr <= addr;
end
endmodule

View File

@@ -0,0 +1,33 @@
`timescale 1ns / 1ps
module writePulseGenerator (input clk,
input snwe,
input sncs,
input reset,
output reg we);
reg w_st;
// write access cpu to bram
always @(posedge clk)
if(~reset) {w_st, we} <= 0;
else begin
case (w_st)
0: begin
we <= 0;
if(sncs | snwe)
w_st <= 1;
end
1: begin
if(~(sncs | snwe))
begin
we <= 1;
w_st <= 0;
end
else we <= 0;
end
endcase
end
endmodule