+ Post New Thread
Results 1 to 12 of 12
  1. #1
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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 bigdogguru; 28th August 2014 at 01:24. Reason: Added CODE or SYNTAX Tags

  2. #2
    Super Moderator
    Points: 31,607, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,310
    Helped
    1719 / 1719
    Points
    31,607
    Level
    43

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

    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.



    •   AltAdvertisement

        
       

  3. #3
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

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



  4. #4
    Super Moderator
    Points: 31,607, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,310
    Helped
    1719 / 1719
    Points
    31,607
    Level
    43

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

    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.



  5. #5
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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.



    •   AltAdvertisement

        
       

  6. #6
    Super Moderator
    Points: 31,607, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,310
    Helped
    1719 / 1719
    Points
    31,607
    Level
    43

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

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


    1 members found this post helpful.

  7. #7
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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;



  8. #8
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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.
    Click image for larger version. 

Name:	20140829022541.png 
Views:	3 
Size:	14.8 KB 
ID:	108791
    Click image for larger version. 

Name:	20140829022658.png 
Views:	3 
Size:	21.2 KB 
ID:	108792

    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...
    Click image for larger version. 

Name:	20140829022951.png 
Views:	6 
Size:	22.7 KB 
ID:	108795



  9. #9
    Super Moderator
    Points: 31,607, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,310
    Helped
    1719 / 1719
    Points
    31,607
    Level
    43

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

    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.



  10. #10
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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?



  11. #11
    Super Moderator
    Points: 31,607, Level: 43
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    7,310
    Helped
    1719 / 1719
    Points
    31,607
    Level
    43

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

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

    Quote Originally Posted by eternalXL View Post
    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.



    •   AltAdvertisement

        
       

  12. #12
    Newbie level 5
    Points: 41, Level: 1

    Join Date
    Aug 2014
    Posts
    8
    Helped
    0 / 0
    Points
    41
    Level
    1

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

    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.




--[[ ]]--