Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problem with test bench for a PS/2 port bidirectional tramsmit

Status
Not open for further replies.

eternalXL

Newbie level 5
Joined
Aug 28, 2014
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
80
Hi

I'm a student doing a project now and I run into some problems about testing two inout signals.

I'm inserting a PS/2 mouse module with Wishbone, but before so I need to test if the signals can really be transferred.

Here is my codes: PS/2 mouse is written in Verilog and I mixed Verilog and VHDL first.


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;



And the principle of the two inout signal ps2d and ps2d is
1. The host forces the ps2c line to be 0 for at least 100 ps to inhibit any mouse activity.
It can be considered that the host requests to send a packet.
2. The host forces the ps2d line to be 0 and disables the ps2c line (i.e., makes it high
impedance). This step can be interpreted as the host sending a start bit.
3. The PS2 device now takes over the ps2c line and is responsible for future PS2 clock
signal generation. After sensing the starting bit, the PS2 device generates a 1-to-0
transition.
4. Once detecting the transition, the host shifts out the least significant data bit over the
ps2d line. It holds this value until the PS2 device generates a 1-to-0 transition in the
ps2c line, which essentially acknowledges retrieval of the data bit.
5. Repeat step 4 for the remaining 7 data bits and 1 parity bit.
6. After sending the parity bit, the host disables the ps2d line (i.e., makes it high impedance).
The PS2 device now takes over the ps2d line and acknowledges completion
of the transmission by asserting the ps2d line to 0. If desired, the host can check this
value at the last 1-to-0 transition in the ps2c line to verify that the packet has been
transmitted successfully.

So for the test bench, I was wondering if I can only be either the device or the host, how can I put value on the inout signals to test...

Thanks a lot for your reading and help.
 
Last edited by a moderator:

So you are trying to test the wishbone mouse RTL?

If so then your (non-existent) zpuino_mouse_test should emulate a host PS2 interface. It should perform the protocol you describe in 1-6.
 

Yes, I'm trying to "act as a mouse" to give value on the ps2d and ps2c lines, to test if the outputs (xm, ym, btnm, m_done_tick) are really giving data to wb_dat_o.
On the test bench, I can only act as the mouse device, but to make the whole system, there should also be data sent from the FPGA side. How I can act as a mouse and a FPGA at the same time. That's something really confuses me now...
 

I wasn't very careful in looking at the code (small phone screen).

First of all you don't show what is in mouse. From the ports I'm assuming xm and ym are positional values of some sort, btnm is that a button signal? I'm assuming ps2d/c is one end of the cable going to the other end of the ps2 cable. The problem with the entity being called mouse is that the xm, ym, and btnm are all outputs of the mouse code. Now a mouse is a HID so I would think that it would take in positional data (input from sensors) and send that data to the PS2 interface. As this entity outputs a positional value it doesn't seem to be a mouse? You should have supplied the code for the mouse code or at least a description of it's function.

Did you think that we are psychic and can see the code through your eyes or in the future when you finally post it?

I also see no reason for having a wishbone interface on your testbench code (zpuino_mouse_test)? If it is testbench code, I have doubts about that.

What you want to have in a testbench (i.e. an emulation of the system)

Host model <-> HID (mouse) <-> ball/button stimulus

This is assuming that your entity is defined incorrectly and the mouse code has inputs for the xm, ym, and btnm.

The host model acts like the PS2 host, the mouse code interfaces the PS2 to the sensors, and the stimulus is a model of the signals that get output from the sensors for ball movement and button presses.
 

Sorry I should have posted the Verilog codes of the PS/2 mouse also.

zpuino_mouse_test is just a name, in this file, I connect the inputs(clk, rst); the outputs(xm, ym, btnm, mouse_done_tick) and the inouts(ps2c and ps2d) with wishbone signals. (After that I will insert the mouse module into a ZPUino). Wishbone is written in VHDL and mouse is written in Verilog so there is also mixed these two HDLs design in the file zpuino_mouse_test (which is not the test bench).

- - - Updated - - -

The intention to make the test bench is to test if the output signals of the ps/2 mouse is transferred to the wishbone signals or not.

Code:
`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

Code:
`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

Code:
`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

Code:
`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

these are the verilog codes for the PS/2 mouse and ZPUino_mouse_test is the top level.
 

Your mouse module isn't the "HID mouse" it's the interface that a host would have for a mouse. Using the name mouse for the module is extremely confusing. Always name files/entities/modules according to their function. It would have been easier to follow if you had called it say mouse_host_if.

So what you currently require is a model of a mouse that sends information of position and button clicks to this host interface "mouse" file. The model will have a similar FSM as is in the mouse module but from the HID perspective. You will have a similar tri-state driver on the HID side. Given the following "1. The host forces the ps2c line to be 0 for at least 100 ps to inhibit any mouse activity." I think 100 ps is incorrect that is a rediculously small duration for something that requires human speed response times. I suspect that is supposed to be 100 us. Also the ps2c and ps2d lines according to the description should be handled as open-drain type signals: e.g. assign ps2c = ps2c ? 1'bz : 1'b0; basically they only drive to the low side otherwise it's tri-state and a pullup resistor is used to give a valid high.
Add the mouse model to the testbench ZPUino_mouse_test and connect the ps2c/ps2d ports together and you can exercise the "mouse host interface" code.

I know this is nit picking, but my advice don't arbitrarily change the name of a signal coming out of a port map just to change the name. I've been working on RTL for a long time, and it's really annoying to perform any kind of search when you have to keep changing the search text every time you change hierarchical boundaries. Besides it also makes it significantly harder to find signals in netlists when you have no idea which of the 15 names used is the one synthesis finally settled on using. Imagine having each bit of a bus with a different name. :p
Besides that tri_d, tri_c sort of implies by most naming conventions that the signal is active high (i.e. tri-state when high), unfortunately these are active-low tri-states.
 
Thanks a lot for your reply. Sorry the very first code with name "ZPUino_mouse_test" is not the test bench. It's the top level that connect the signals of the host_mouse_is (as you said) to the Wishbone.
Here is my codes of the test bench:
Code:
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;
 

Thanks again for suggesting me to change all the same lines with the same name, the RTL schematic looks better now.
The receiving subsystem goes first then the transmitting system, and here are two timing diagrams for the two subsystems, that's the idea I got for my test bench.
20140829022541.png
20140829022658.png

Yes it should be 100 us. I did so on my test bench.

But the results are still wrong. I gave value to the inout ps2c and ps2d, and nothing shows up from the outputs (xm, ym ...)

And even when I was trying to set a reset first, the ps2c line cannot be "1" then...
20140829022951.png
 

You've got two drivers on the same signal ps2c that are driving opposite values so you get an x. That's why i suggested you change the tri-states to only drive 0 and tristate when 1. Add a pullup (weak 1) to the signal on the testbench.
 

Sorry I'm not fully familiar with this existing codes from a book. Could I guess the problem is in the transmitter subsystem(ps2_tx)? 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?
 

Seems like you need to learn how to debug.

Try adding the FSMs that drive each end of the PS2 and the tri signals that enable the ps2c/d signals on your waveform and rerun the simulation to see why you are getting a conflict. I suspect you are driving a 0 on the ps2c signal instead of on the tri_c signal to tri-state it.

Regards

- - - Updated - - -

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?
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.

- - - Updated - - -

Sorry I probably should have looked at your testbench. I see now that you haven't taken any of my advice as to how to build a testbench, so your not using a model of a "mouse" to drive the ps2c/ps2d to the poorly named "mouse" module.

You are always driving the ps2c and ps2d values in the testbench, therefore when the ps2c is driven by the "mouse" module it conflicts with the testbench. This is why I suggested creating a model to drive the other end of the ps2 connection.
 

Yes. Last night I got rid of the transmit subsystem and the Wishbone connect level, just tested the mouse module with receive subsystem but there was still nothing showed up in the outputs of the mouse module (xm, ym, ...) Here is a picture showing how the whole project looks like now, following with a pic showing the results. I don't know if you can see the pics with your mobile phone.

 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top