PS2 Keyboard and RAM block interaction Verilog

Guest #4799391
Rate this post
• ▲ useful
▼ not useful
Hi, I am working on a circuit for FPGA that would take input from a ps2 
keyboard and write it into a ram block (storing each letter) so that the 
data can be used later and outputted on VGA. I had the ps2 keyboard 
working in a simple module that directly outputs the data onto a hex but 
when I tried to incorporate a ram block into said circuit, it did not 
work. Could someone please help me see what I am doing wrong, no matter 
how many times I modified the FSM, I still had no new output going to 
hex.

For now, I have only tried the case for 1 letter.

Code:

module keyTest (KEY, CLOCK_50, PS2_CLK, PS2_DAT, HEX0, HEX2);

    input [3:0] KEY;
    input CLOCK_50;
    inout PS2_CLK, PS2_DAT;
    output [6:0] HEX0, HEX2;

    wire reset, go1, go2, enable, print;

    assign go1 = ~KEY[1];
    assign go2 = ~KEY[2];
    assign reset = KEY[0];

    wire [7:0] letter;

    // Internal Wires
    wire [7:0]  ps2_key_data;
    wire ps2_key_pressed;

    // Internal Registers
    reg  [7:0]  last_data_received;
    wire [7:0] hex_data, address;

    wire [8:0] counter, print_counter;


    //assigning new data for write-in if data received from keyboard
    always @(posedge CLOCK_50)
        begin
            if (!reset)
                last_data_received <= 8'h00;
            else if (ps2_key_pressed == 1'b1)
                last_data_received <= ps2_key_data;

     end


    //ps2 control
    PS2_Controller PS2 (.CLOCK_50(CLOCK_50), .reset(~reset), 
.PS2_CLK(PS2_CLK), .PS2_DAT(PS2_DAT), .received_data(ps2_key_data), 
.received_data_en(ps2_key_pressed));



  //storing ram up to 256 8 bit character
    inputRam256x8 u0 (.address(address), .clock(CLOCK_50), 
.data(last_data_received), .wren(enable), .q(letter));


    control a1 (.clock(CLOCK_50), .reset(reset), .go1(go1), .go2(go2), 
.ps2_key_pressed(ps2_key_pressed), .enable(enable), .print(print), 
.counter(counter), .print_counter(print_counter));
    datapath a2 (.clock(CLOCK_50), .reset(reset), .enable(enable), 
.print(print), .last_data_received(last_received_data), .letter(letter), 
.counter(counter), .print_counter(print_coutner), .hex_data(hex_data), 
.address(address));


    hex_decoder m0 (.hex_digit(hex_data[3:0]), .segments(HEX0));
    hex_decoder m1 (.hex_digit(hex_data[7:0]), .segments(HEX2));


endmodule

module control (clock, reset, go1, go2, ps2_key_pressed, enable, print, 
counter, print_counter);

     input clock, reset, go1, go2, ps2_key_pressed;
     output reg enable, print;
     output reg [8:0] counter, print_counter;
     reg [5:0] current_state, next_state;

     localparam S_READ_PS2       = 5'd0, //read in data from ps2
                S_WRITE          = 5'd1, //write data into ram
          S_WAIT1     = 5'd2, //wait for a signal to go to wait2
                S_PRINT          = 5'd3, //print every letter on hex
    S_WAIT2           = 5'd4, //wait for signal to either continue 
reading data or start printing
          S_READ_WAIT      = 5'd6; //wait for new input to start reading


    // Next state logic aka our state table
    always@(*)
    begin: state_table
        case (current_state)
    S_READ_WAIT: next_state = ps2_key_pressed ? S_READ_PS2 : 
S_READ_WAIT;
          S_READ_PS2: next_state = ps2_key_pressed ? S_READ_PS2 : 
S_WRITE;
          S_WRITE: next_state = (counter == 9'b100000000) ? S_PRINT : 
S_WAIT1;
    S_WAIT1: next_state = go1 ? S_WAIT2 : S_WAIT1;
    S_WAIT2: next_state =  go2 ? S_PRINT: S_READ_WAIT;
    S_PRINT: next_state = (print_counter <= counter) ? S_PRINT : 
S_READ_WAIT;
          default: next_state = S_READ_WAIT;
        endcase
    end // state_table

  // Output logic aka all of our datapath control signals
    always @(*)
    begin: enable_signals
        // By default make all our signals 0
    enable = 1'b0;
    print = 1'b0;

        case (current_state)
            S_READ_PS2: begin
      enable = 1'b0;
      end
      S_WRITE: begin
      enable = 1'b1;
      end
      S_PRINT: begin
      enable = 1'b0;
      print = 1'b1;
      end
        // default:    // don't need default since we already made sure 
all of our outputs were assigned a value at the start of the always 
block
        endcase
    end // enable_signals

  initial counter = 9'd0;

  //count up to 256 to make sure there is available memory space
    always @(posedge clock)
        begin
            if (!reset) begin
      counter <= 9'b00000000;
      end
            else if (counter == 9'b100000000)
      counter <= 9'b000000000;
            else if (current_state == S_WRITE)
      counter <= counter + 1'b1;
        end

     initial print_counter = 9'd0;

     always @(posedge clock)
         begin
            if (!reset) begin
      print_counter <= 9'b00000000;
      end
            else if (print_counter == 9'b100000000)
      print_counter <= 9'b000000000;
            else if (current_state == S_PRINT)
      print_counter <= print_counter + 1'b1;
        end

endmodule


module datapath (clock, reset, enable, print, last_data_received, 
letter, counter, print_counter, hex_data, address);

     input clock, reset, enable, print;
     input [7:0] last_data_received, letter;
     input [8:0] counter, print_counter;
     output reg [7:0] hex_data, address;

     always @(posedge clock) begin
      if(!reset)
    hex_data <= 8'd0;
      else if (print)
    hex_data <= letter;
     end

     always @(posedge clock) begin
      if(!reset)
    address <= 8'd0;
      else if (print)
    address <= print_counter[7:0];
    else if (enable)
      address <= counter[7:0];
  end


endmodule


//hex module for test
module hex_decoder(hex_digit, segments);

    input [3:0] hex_digit;
    output reg [6:0] segments;

    always @(*)
        case (hex_digit)
            4'h0: segments = 7'b100_0000;
            4'h1: segments = 7'b111_1001;
            4'h2: segments = 7'b010_0100;
            4'h3: segments = 7'b011_0000;
            4'h4: segments = 7'b001_1001;
            4'h5: segments = 7'b001_0010;
            4'h6: segments = 7'b000_0010;
            4'h7: segments = 7'b111_1000;
            4'h8: segments = 7'b000_0000;
            4'h9: segments = 7'b001_1000;
            4'hA: segments = 7'b000_1000;
            4'hB: segments = 7'b000_0011;
            4'hC: segments = 7'b100_0110;
            4'hD: segments = 7'b010_0001;
            4'hE: segments = 7'b000_0110;
            4'hF: segments = 7'b000_1110;
            default: segments = 7'h7f;
        endcase
endmodule
#4800463
Rate this post
• ▲ useful
▼ not useful
First, please mark code in tags so that it appears readable.

Second, I can't read Verilog, sorry.

Then, split your problem in multiple parts and test each of those:
- in PS/2, the keyboard decides the clock, so you must
  synchronize the CLK and DATA lines with out FPGA clock;
- the keyboard will send multiple bytes for each key press, example:
  "0x1C" means "A pushed down", and "0xF0, 0x1C" means "A released",
  so you need to build a shift register to receive each byte separately
  and turn those into a byte stream (scancode)
- this byte stream should be fed into a state machine to turn it into
  a set of events handling keys
- whenever you get a key event you are interested in, you feed it into
  another FSM to write it to memory (in order to read memory, you need
  a FSM anyway, so don't bother doing without)

Simulate each step!

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.