Intel® FPGA University Program
University Program Material, Education Boards, and Laboratory Exercises

FPGA - PC communication

Altera_Forum
Honored Contributor II
2,661 Views

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
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
1,374 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
1,374 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
1,374 Views

Thanks much! RS232 it is:).

0 Kudos
Altera_Forum
Honored Contributor II
1,375 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
1,375 Views

 

--- 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.
0 Kudos
Reply