Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

FPGA - PC communication

Hey all, I am trying to get my DE2-115 board and my pc to communicate, but I have no idea where to even start. So far my FPGA training begins and ends with the 10 labs that came with the DE board, plus a few projects I did for fun. So, I have two questions:

1. Given that I have no knowledge of communication protocols and such, would it be easiest for me to learn and implement USB, Ethernet, or RS232?

2. Based on your answer to the first, can you please suggest some learning resources I could consult?

Much Appreciated

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    RS232 is by far the easiest to implement. Many products still include RS232 as it is easy and cheap to implement on the FPGA and works with little debugging. Ethernet and USB are both massively complex. You cannot find USB or Ethernet cores for free.

    There are plenty of RS232 examples if you use google. Here is the first: http://www.fpga4fun.com/serialinterface.html
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Very few of the current PCs have an RS-232 port, but USB to RS-232 adapters are available.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hey just try my code - I have programmed the RS232 successfully today:

    //*******************************************************

    //****** PAVLE DUKANOVIC *******

    //****** www.dukelanovic.com *******

    //****** dukelanovic@yahoo.de *******

    //*******************************************************

    // Serial port demo program

    // http://www.techques.com/question/4-13718/implement-serial-port-on-fpga-(verilog)

    // Assumptions: 50Mhz clock rate

    module serial(input clk,input key_in, output ser, input rxd);

    // Start signal tells it to start sending bits

    reg[24:0]count;

    reg [3:0] ones;

    reg [3:0] tens;

    //The bits of data to send

    reg [7:0] data;

    reg sec;

    reg [14:0] clockdiv;

    reg [14:0] clockdivrx;

    // Output register to pin

    assign ser = outbit;

    // Count from 0..5207 then reset back to zero (9600 Baud for TX)

    always @(posedge clk)

    begin

    if (clockdiv == 5207)

    clockdiv <= 0;

    else

    clockdiv <= clockdiv + 1;

    end

    // Count from 0..5207 then reset back to zero (9600 Baud for TX)

    always @(posedge clk)

    begin

    if (clockdivrx == 1302)

    clockdivrx <= 0;

    else

    clockdivrx <= clockdivrx + 1;

    end

    // The serclock is a short pulse each time we are reset

    wire serclock = (clockdiv == 0);

    wire start = (clockdiv == 0);

    wire serclockrx = (clockdivrx == 0);

    /////////////////////////////////////////////////////////////////////////////

    // Serial port state machine

    // Only start the state machine when "start" is set. Only advance to the

    // next state when serclock is set.

    reg [3:0] state;

    always @(posedge clk)

    begin

    case (state)

    4'b0000: if (start) state <= 4'b0001;

    4'b0001: if (serclock) state <= 4'b0010; // Start bit

    4'b0010: if (serclock) state <= 4'b0011; // Bit 0

    4'b0011: if (serclock) state <= 4'b0100; // Bit 1

    4'b0100: if (serclock) state <= 4'b0101; // Bit 2

    4'b0101: if (serclock) state <= 4'b0110; // Bit 3

    4'b0110: if (serclock) state <= 4'b0111; // Bit 4

    4'b0111: if (serclock) state <= 4'b1000; // Bit 5

    4'b1000: if (serclock) state <= 4'b1001; // Bit 6

    4'b1001: if (serclock) state <= 4'b1010; // Bit 7

    4'b1010: if (serclock) state <= 4'b0000; // Stop bit

    default: state <= 4'b0000; // Undefined, skip to stop

    endcase

    end

    ///////////////////////////////////////////////////////////////////////////////

    // Serial port data

    // Ensure that the serial port has the correct data on it in each state

    reg outbit;

    always @(posedge clk)

    begin

    case (state)

    4'b0000: outbit <= 1; // idle

    4'b0001: outbit <= 0; // Start bit

    4'b0010: outbit <= data[0]; // Bit 0

    4'b0011: outbit <= data[1]; // Bit 1

    4'b0100: outbit <= data[2]; // Bit 2

    4'b0101: outbit <= data[3]; // Bit 3

    4'b0110: outbit <= data[4]; // Bit 4

    4'b0111: outbit <= data[5]; // Bit 5

    4'b1000: outbit <= data[6]; // Bit 6

    4'b1001: outbit <= data[7]; // Bit 7

    4'b1010: outbit <= 0; // Stop bit

    default: outbit <= 1;df // Bad state output idle

    endcase

    end

    reg [7:0] charstate;

    reg [5:0] rxstate;

    always @(posedge clk)

    begin

    case (rxstate)

    6'b000000: if (!rxd) rxstate <= 4'b000001;

    6'b000001: if (serclockrx) rxstate <= 6'b000010;

    6'b000010: if (serclockrx) rxstate <= 6'b000011;

    6'b000011: if (serclockrx) rxstate <= 6'b000100;

    6'b000100: if (serclockrx) rxstate <= 6'b000101;

    6'b000101: if (serclockrx) rxstate <= 6'b000110;

    6'b000110: if (serclockrx) begin rxstate <= 6'b000111; data[0] <= rxd; end // The sixth tact LSB reg [7:0] data;

    6'b000111: if (serclockrx) rxstate <= 6'b001000;

    6'b001000: if (serclockrx) rxstate <= 6'b001001;

    6'b001001: if (serclockrx) rxstate <= 6'b001010;

    6'b001010: if (serclockrx) begin rxstate <= 6'b001011; data[1] <= rxd; end // The 10'th tact

    6'b001011: if (serclockrx) rxstate <= 6'b001100;

    6'b001100: if (serclockrx) rxstate <= 6'b001101;

    6'b001101: if (serclockrx) rxstate <= 6'b001110;

    6'b001110: if (serclockrx) begin rxstate <= 6'b001111; data[2] <= rxd; end // The 14'th tact

    6'b001111: if (serclockrx) rxstate <= 6'b010000;

    6'b010000: if (serclockrx) rxstate <= 6'b010001;

    6'b010001: if (serclockrx) rxstate <= 6'b010010;

    6'b010010: if (serclockrx) begin rxstate <= 6'b010011; data[3] <= rxd; end // The 18'th tact

    6'b010011: if (serclockrx) rxstate <= 6'b010100;

    6'b010100: if (serclockrx) rxstate <= 6'b010101;

    6'b010101: if (serclockrx) rxstate <= 6'b010110;

    6'b010110: if (serclockrx) begin rxstate <= 6'b010111; data[4] <= rxd; end // The 22'nd tact

    6'b010111: if (serclockrx) rxstate <= 6'b011000;

    6'b011000: if (serclockrx) rxstate <= 6'b011001;

    6'b011001: if (serclockrx) rxstate <= 6'b011010;

    6'b011010: if (serclockrx) begin rxstate <= 6'b011011; data[5] <= rxd; end // The 26'th tact

    6'b011011: if (serclockrx) rxstate <= 6'b011100;

    6'b011100: if (serclockrx) rxstate <= 6'b011101;

    6'b011101: if (serclockrx) rxstate <= 6'b011110;

    6'b011110: if (serclockrx) begin rxstate <= 6'b011111; data[6] <= rxd; end // The 30'th tact

    6'b011111: if (serclockrx) rxstate <= 6'b100000;

    6'b100000: if (serclockrx) rxstate <= 6'b100001;

    6'b100001: if (serclockrx) rxstate <= 6'b100010;

    6'b100010: if (serclockrx) begin rxstate <= 6'b100011; data[7] <= rxd; end // The 34'th tact

    6'b100011: if (serclockrx) rxstate <= 6'b100100;

    6'b100100: if (serclockrx) rxstate <= 6'b100101;

    6'b100101: if (serclockrx) rxstate <= 6'b100110;

    default: rxstate <= 6'b000000;

    endcase

    end

    endmodule

    There only one problem remained in the whole story - as I have been pressing a key in Putty.exe the module always was sending

    characters. So is here somebody who could give me a hint how I could program the whole story so that the module sends back only

    one character?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hey just try my code - I have programmed the RS232 successfully today:

    //*******************************************************

    //****** PAVLE DUKANOVIC *******

    //****** www.dukelanovic.com (http://www.dukelanovic.com) *******

    //****** dukelanovic@yahoo.de *******

    //*******************************************************

    // Serial port demo program

    // http://www.techques.com/question/4-13718/implement-serial-port-on-fpga-(verilog)

    // Assumptions: 50Mhz clock rate

    module serial(input clk,input key_in, output ser, input rxd);

    // Start signal tells it to start sending bits

    reg[24:0]count;

    reg [3:0] ones;

    reg [3:0] tens;

    //The bits of data to send

    reg [7:0] data;

    reg sec;

    reg [14:0] clockdiv;

    reg [14:0] clockdivrx;

    // Output register to pin

    assign ser = outbit;

    // Count from 0..5207 then reset back to zero (9600 Baud for TX)

    always @(posedge clk)

    begin

    if (clockdiv == 5207)

    clockdiv <= 0;

    else

    clockdiv <= clockdiv + 1;

    end

    // Count from 0..5207 then reset back to zero (9600 Baud for TX)

    always @(posedge clk)

    begin

    if (clockdivrx == 1302)

    clockdivrx <= 0;

    else

    clockdivrx <= clockdivrx + 1;

    end

    // The serclock is a short pulse each time we are reset

    wire serclock = (clockdiv == 0);

    wire start = (clockdiv == 0);

    wire serclockrx = (clockdivrx == 0);

    /////////////////////////////////////////////////////////////////////////////

    // Serial port state machine

    // Only start the state machine when "start" is set. Only advance to the

    // next state when serclock is set.

    reg [3:0] state;

    always @(posedge clk)

    begin

    case (state)

    4'b0000: if (start) state <= 4'b0001;

    4'b0001: if (serclock) state <= 4'b0010; // Start bit

    4'b0010: if (serclock) state <= 4'b0011; // Bit 0

    4'b0011: if (serclock) state <= 4'b0100; // Bit 1

    4'b0100: if (serclock) state <= 4'b0101; // Bit 2

    4'b0101: if (serclock) state <= 4'b0110; // Bit 3

    4'b0110: if (serclock) state <= 4'b0111; // Bit 4

    4'b0111: if (serclock) state <= 4'b1000; // Bit 5

    4'b1000: if (serclock) state <= 4'b1001; // Bit 6

    4'b1001: if (serclock) state <= 4'b1010; // Bit 7

    4'b1010: if (serclock) state <= 4'b0000; // Stop bit

    default: state <= 4'b0000; // Undefined, skip to stop

    endcase

    end

    ///////////////////////////////////////////////////////////////////////////////

    // Serial port data

    // Ensure that the serial port has the correct data on it in each state

    reg outbit;

    always @(posedge clk)

    begin

    case (state)

    4'b0000: outbit <= 1; // idle

    4'b0001: outbit <= 0; // Start bit

    4'b0010: outbit <= data[0]; // Bit 0

    4'b0011: outbit <= data[1]; // Bit 1

    4'b0100: outbit <= data[2]; // Bit 2

    4'b0101: outbit <= data[3]; // Bit 3

    4'b0110: outbit <= data[4]; // Bit 4

    4'b0111: outbit <= data[5]; // Bit 5

    4'b1000: outbit <= data[6]; // Bit 6

    4'b1001: outbit <= data[7]; // Bit 7

    4'b1010: outbit <= 0; // Stop bit

    default: outbit <= 1;df // Bad state output idle

    endcase

    end

    reg [7:0] charstate;

    reg [5:0] rxstate;

    always @(posedge clk)

    begin

    case (rxstate)

    6'b000000: if (!rxd) rxstate <= 4'b000001;

    6'b000001: if (serclockrx) rxstate <= 6'b000010;

    6'b000010: if (serclockrx) rxstate <= 6'b000011;

    6'b000011: if (serclockrx) rxstate <= 6'b000100;

    6'b000100: if (serclockrx) rxstate <= 6'b000101;

    6'b000101: if (serclockrx) rxstate <= 6'b000110;

    6'b000110: if (serclockrx) begin rxstate <= 6'b000111; data[0] <= rxd; end // The sixth tact LSB reg [7:0] data;

    6'b000111: if (serclockrx) rxstate <= 6'b001000;

    6'b001000: if (serclockrx) rxstate <= 6'b001001;

    6'b001001: if (serclockrx) rxstate <= 6'b001010;

    6'b001010: if (serclockrx) begin rxstate <= 6'b001011; data[1] <= rxd; end // The 10'th tact

    6'b001011: if (serclockrx) rxstate <= 6'b001100;

    6'b001100: if (serclockrx) rxstate <= 6'b001101;

    6'b001101: if (serclockrx) rxstate <= 6'b001110;

    6'b001110: if (serclockrx) begin rxstate <= 6'b001111; data[2] <= rxd; end // The 14'th tact

    6'b001111: if (serclockrx) rxstate <= 6'b010000;

    6'b010000: if (serclockrx) rxstate <= 6'b010001;

    6'b010001: if (serclockrx) rxstate <= 6'b010010;

    6'b010010: if (serclockrx) begin rxstate <= 6'b010011; data[3] <= rxd; end // The 18'th tact

    6'b010011: if (serclockrx) rxstate <= 6'b010100;

    6'b010100: if (serclockrx) rxstate <= 6'b010101;

    6'b010101: if (serclockrx) rxstate <= 6'b010110;

    6'b010110: if (serclockrx) begin rxstate <= 6'b010111; data[4] <= rxd; end // The 22'nd tact

    6'b010111: if (serclockrx) rxstate <= 6'b011000;

    6'b011000: if (serclockrx) rxstate <= 6'b011001;

    6'b011001: if (serclockrx) rxstate <= 6'b011010;

    6'b011010: if (serclockrx) begin rxstate <= 6'b011011; data[5] <= rxd; end // The 26'th tact

    6'b011011: if (serclockrx) rxstate <= 6'b011100;

    6'b011100: if (serclockrx) rxstate <= 6'b011101;

    6'b011101: if (serclockrx) rxstate <= 6'b011110;

    6'b011110: if (serclockrx) begin rxstate <= 6'b011111; data[6] <= rxd; end // The 30'th tact

    6'b011111: if (serclockrx) rxstate <= 6'b100000;

    6'b100000: if (serclockrx) rxstate <= 6'b100001;

    6'b100001: if (serclockrx) rxstate <= 6'b100010;

    6'b100010: if (serclockrx) begin rxstate <= 6'b100011; data[7] <= rxd; end // The 34'th tact

    6'b100011: if (serclockrx) rxstate <= 6'b100100;

    6'b100100: if (serclockrx) rxstate <= 6'b100101;

    6'b100101: if (serclockrx) rxstate <= 6'b100110;

    default: rxstate <= 6'b000000;

    endcase

    end

    endmodule

    There only one problem remained in the whole story - as I have been pressing a key in Putty.exe the module always was sending

    characters. So is here somebody who could give me a hint how I could program the whole story so that the module sends back only

    one character?

    --- Quote End ---

    Your stop bit is 0. Needs to be 1.