Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; library UNISIM; use UNISIM.VComponents.all; entity zpuino_mouse_test is port( wb_clk_i: in std_logic; wb_rst_i: in std_logic; wb_dat_o: out std_logic_vector(15 downto 0); wb_adr_i: in std_logic_vector(3 downto 0); wb_cyc_i: in std_logic; wb_stb_i: in std_logic; wb_ack_o: out std_logic; wb_inta_o:out std_logic; --zpuino_mouse interface ps2dz: inout std_logic; ps2cz: inout std_logic ); end zpuino_mouse_test; architecture Behavioral of zpuino_mouse_test is component mouse is port( clk: in std_logic; reset: in std_logic; ps2d: inout std_logic; ps2c: inout std_logic; xm: out std_logic_vector(8 downto 0); ym: out std_logic_vector(8 downto 0); btnm: out std_logic_vector(2 downto 0); m_done_tick: out std_logic ); end component mouse; signal xmz: std_logic_vector(8 downto 0); signal ymz: std_logic_vector(8 downto 0); signal btnmz: std_logic_vector(2 downto 0); signal m_done_tickz: std_logic ; begin m1 : mouse port map( clk => wb_clk_i, reset => wb_rst_i, ps2d => ps2dz, ps2c => ps2cz, xm => xmz, ym => ymz, btnm => btnmz, m_done_tick => m_done_tickz); wb_ack_o <= wb_cyc_i and wb_stb_i; wb_inta_o <= '0'; process (wb_clk_i,wb_rst_i,wb_adr_i) begin if wb_rst_i = '1' then wb_dat_o <= (others => 'X'); elsif (wb_clk_i'event and wb_clk_i='1') then case wb_adr_i(2) is when '0' => wb_dat_o(8 downto 0) <= xmz; wb_dat_o(11 downto 9) <= btnmz; wb_dat_o(12) <=m_done_tickz; when '1' => wb_dat_o(8 downto 0) <= ymz; wb_dat_o(11 downto 9) <= btnmz; wb_dat_o(12) <=m_done_tickz; when others => wb_dat_o <= (others => 'X'); end case; end if; end process; end Behavioral;
`timescale 1ns / 1ps
module ps2_tx
(
input wire clk, reset,
input wire wr_ps2,
input wire [7:0] din,
inout wire ps2d, ps2c,
output reg tx_idle, tx_done_tick
);
// 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;
// body
//========================================================
// filter and falling-edge tick generation for ps2c
//========================================================
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 = {ps2c, 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;
//=======================================================
// FSMD
//=======================================================
// FSMD 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);
// FSMD next-state logic
always @*
begin
state_next = state_reg;
c_next = c_reg;
n_next = n_reg;
b_next = b_reg;
tx_done_tick = 1'b0;
ps2c_out = 1'b1;
ps2d_out = 1'b1;
tri_c = 1'b0;
tri_d = 1'b0;
tx_idle = 1'b0;
case (state_reg)
idle:
begin
tx_idle = 1'b1;
if (wr_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];
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 ps2d
if (fall_edge)
begin state_next = idle;
tx_done_tick= 1'b1;
end
endcase
end
//tri-state buffers
assign ps2c= (tri_c)? ps2c_out:1'bz;
assign ps2d= (tri_d)?ps2d_out:1'bz;
endmodule
`timescale 1ns / 1ps
module ps2_rx(
input wire clk, reset,
input wire ps2d, ps2c, rx_en,
output reg rx_done_tick,
output wire [7:0] dout
);
// symbolic state declaration
localparam [1:0]
idle = 2'b00,
dps = 2'b01,
load = 2'b10;
// 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;
// body
//=================================================
// filter and falling-edge tick generation for ps2c
//=================================================
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 = {ps2c, 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;
//==========================================
// FSMD
//==========================================
// FSMD state & data registers
always @ (posedge clk , posedge reset)
if (reset)
begin
state_reg <= idle;
n_reg <= 0;
b_reg <= 0;
end
else
begin
state_reg <= state_next ;
n_reg <= n_next;
b_reg <= b_next;
end
// FSMD next-state logic
always @*
begin
state_next = state_reg;
rx_done_tick = 1'b0;
n_next = n_reg;
b_next = b_reg;
case (state_reg)
idle:
if (fall_edge & rx_en)
begin
// shift in start bit
b_next = {ps2d, b_reg [10:1] };
n_next = 4'b1001;
state_next = dps;
end
dps: // 8 data + 1 parity + 1 stop
if (fall_edge)
begin
b_next = {ps2d, b_reg [10:1]} ;
if (n_reg==0)
state_next = load;
else
n_next = n_reg - 1;
end
load: // 1 extra clock to complete the last shift
begin
state_next = idle;
rx_done_tick = 1'b1;
end
endcase
end
//output
assign dout = b_reg[8:1]; // data bits
endmodule
`timescale 1ns / 1ps
module ps2_rxtx(
input wire clk, reset,
input wire wr_ps2,
inout wire ps2d, ps2c,
input wire [7:0] din,
output wire rx_done_tick, tx_done_tick ,
output wire [7:0] dout
);
// signal declaration
wire tx_idle;
// body
// instantiate ps2 receiver
ps2_rx ps2_rx_unit
(.clk(clk), .reset(reset), .rx_en(tx_idle),
.ps2d (ps2d), .ps2c (ps2c),
.rx_done_tick(rx_done_tick), .dout(dout));
// instantiate ps2 transmitter
ps2_tx ps2_tx_unit
(.clk(clk), .reset(reset), .wr_ps2(wr_ps2),
.din(din), .ps2d(ps2d), .ps2c(ps2c),
.tx_idle(tx_idle), .tx_done_tick(tx_done_tick));
endmodule
`timescale 1ns / 1ps
module mouse(
input wire clk, reset,
inout wire ps2d, ps2c,
output wire [8:0] xm, ym,
output wire [2:0] btnm,
output reg m_done_tick
);
// constant declaration
localparam STRM=8'hf4; // stream command F4
// symbolic state declaration
localparam [2:0]
init1 = 3'b000,
init2 = 3'b001,
init3 = 3'b010,
pack1 = 3'b011,
pack2 = 3'b100,
pack3 = 3'b101,
done = 3'b110;
// signal declaration
reg [2:0] state_reg , state_next;
wire [7:0] rx_data;
reg wr_ps2;
wire rx_done_tick , tx_done_tick;
reg [8:0] x_reg, y_reg, x_next, y_next;
reg [2:0] btn_reg , btn_next;
// body
// instantiation
ps2_rxtx ps2_unit
(.clk(clk), .reset(reset), .wr_ps2(wr_ps2),
.din(STRM), .dout(rx_data), .ps2d(ps2d), .ps2c(ps2c),
.rx_done_tick(rx_done_tick),
.tx_done_tick(tx_done_tick));
// body
// FSMD state and data registers
always @ (posedge clk , posedge reset)
if (reset)
begin
state_reg <= init1;
x_reg <= 0;
y_reg <= 0;
btn_reg <= 0;
end
else
begin
state_reg <= state_next;
x_reg <= x_next;
y_reg <= y_next;
btn_reg <= btn_next;
end
// FSMD next-state logic
always @*
begin
state_next = state_reg;
wr_ps2 = 1'b0;
m_done_tick = 1'b0;
x_next = x_reg;
y_next = y_reg;
btn_next = btn_reg;
case (state_reg)
init1:
begin
wr_ps2 = 1'b1;
state_next = init2;
end
init2: // wait for send to complete
if (tx_done_tick)
state_next = init3;
init3: // wait for acknowledge packet
if (rx_done_tick)
state_next = pack1;
pack1: // wait for 1st data packet
if (rx_done_tick)
begin
state_next = pack2;
y_next[8] = rx_data[5];
x_next[8] = rx_data[4];
btn_next = rx_data[2:0];
end
pack2: // wait for 2nd data packet
if (rx_done_tick)
begin
state_next = pack3;
x_next [7:0] = rx_data;
end
pack3: // wait for 3rd data packet
if (rx_done_tick)
begin
state_next = done;
y_next[7:0] = rx_data;
end
done:
begin
m_done_tick = 1'b1;
state_next = pack1;
end
endcase
end
//output
assign xm = x_reg;
assign ym = y_reg;
assign btnm = btn_reg;
endmodule
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY lwzmtest IS
END lwzmtest;
ARCHITECTURE behavior OF lwzmtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT zpuino_mouse_test
PORT(
wb_clk_i : IN std_logic;
wb_rst_i : IN std_logic;
wb_dat_o : OUT std_logic_vector(15 downto 0);
wb_adr_i : IN std_logic_vector(3 downto 0);
wb_cyc_i : IN std_logic;
wb_stb_i : IN std_logic;
wb_ack_o : OUT std_logic;
wb_inta_o : OUT std_logic;
ps2d : INOUT std_logic;
ps2c : INOUT std_logic
);
END COMPONENT;
--Inputs
signal wb_clk_i : std_logic := '0';
signal wb_rst_i : std_logic := '0';
signal wb_adr_i : std_logic_vector(3 downto 0) := (others => '0');
signal wb_cyc_i : std_logic := '0';
signal wb_stb_i : std_logic := '0';
signal xm: std_logic_vector(8 downto 0);
signal ym: std_logic_vector(8 downto 0);
signal btnm: std_logic_vector(2 downto 0);
--signal xmz: std_logic_vector(8 downto 0) := (others => '0');
-- signal ymz: std_logic_vector(8 downto 0) := (others => '0');
-- signal btnmz: std_logic_vector(2 downto 0) := (others => '0');
signal m_done_tick: std_logic ;
--BiDirs
signal ps2d : std_logic;
signal ps2c : std_logic;
--Outputs
signal wb_dat_o : std_logic_vector(15 downto 0);
signal wb_ack_o : std_logic;
signal wb_inta_o : std_logic;
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
constant wb_clk_i_period : time := 80 us;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: zpuino_mouse_test PORT MAP (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_dat_o => wb_dat_o,
wb_adr_i => wb_adr_i,
wb_cyc_i => wb_cyc_i,
wb_stb_i => wb_stb_i,
wb_ack_o => wb_ack_o,
wb_inta_o => wb_inta_o,
ps2d => ps2d,
ps2c => ps2c
);
-- Clock process definitions
wb_clk_process :process
begin
wb_clk_i <= '0';
wait for wb_clk_i_period/2;
wb_clk_i <= '1';
wait for wb_clk_i_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 40 us;
wb_rst_i <= '1';
wait for 40 us;
wb_rst_i <= '0';
wait for 120 us;
ps2d <= '0';
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--1
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--2
ps2d <= '1';
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--3
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--4
ps2c <= '1';
ps2d <='0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--5
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--6
ps2c <= '1';
ps2d <='1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--7
ps2c <= '0';
ps2d <='1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--8
ps2c <= '1';
ps2d <='0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--9
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--10
ps2c <= '1';
ps2d <='1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--11
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--12
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--13
ps2c <= '0';
ps2d <='1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--14
ps2c <= '1';
ps2d <='0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--15
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--16
ps2c <= '1';
ps2d <='1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--17
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--18
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--19
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--20
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 160 us;--21
ps2d <= '0';
ps2c <= 'Z';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 80 us;--22
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--23
ps2c <= '0';
ps2d <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--24
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--25
ps2c <= '0';
ps2d <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--26
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--27
ps2c <= '0';
ps2d <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--28
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--29
ps2c <= '0';
ps2d <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--30
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--31
ps2c <= '0';
ps2d <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--32
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--33
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--34
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--35
ps2c <= '0';
ps2d <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--36
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--37
ps2c <= '0';
ps2d <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--38
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--39
ps2c <= '0';
ps2d <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--40
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--41
ps2c <= '0';
ps2d <= 'Z';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--42
ps2c <= '1';
ps2d <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--43
ps2c <= '0';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 40 us;--44
ps2c <= '1';
wb_adr_i <= "0000";
wb_stb_i <= '1';
wb_cyc_i <= '1';
wait for 80 us;
wait;
end process;
END;
I wouldn't do this. I would look at tri_c and tri_d and the FSM to see where it is in protocol you described. Either it's not following the protocol you described or it's enabling the tri_c when it shouldn't. Check this first, don't just edit the mouse.v file.If I need to test the receiving first, the tri_c and tri_d should all be 0 then the ps2d and ps2d can be seen as only inputs? but how to make the change in the mouse.v file?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?