- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear readers - I have been programming following code:
//******************************************************* //****** 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 endmodulethe rs232 transmitter is always sending if i type in a character into my pc
please help me to fix taht problem.
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- The RS232 transmitter is always sending if I type in a character into my PC --- Quote End --- This is correct, according to your code. Infact you assert 'start' periodically when clockdiv==0.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- This is correct, according to your code. Infact you assert 'start' periodically when clockdiv==0. --- Quote End --- Thank you Cris72 I also was born in 72. For now my plan is to write a book about the Chinese module A-C8V4 that uses a Cyclone II chip. I am going through all examples and for now I do not have an idea what I could program here. Surely start is always called when clockdiv==0.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Thank you Cris72 I also was born in 72. For now my plan is to write a book about the Chinese module A-C8V4 that uses a Cyclone II chip. I am going through all examples and for now I do not have an idea what I could program here. Surely start is always called when clockdiv==0. --- Quote End --- Please help me because I do not know how to start that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Please help me because I do not know how to start that. --- Quote End --- I can't help you if you don't specify what your design is supposed to do. You should assert 'start' only when you really want your fpga to transmit something. You can use the rising edge of an input signal (for example, what's the purpose of key_in signal? you could possibly use this). Otherwise, if you may want your board to transmit back when it receives data: in this case you could assert start when rxstate=6'b100110 Advice: That rxstate case statement is very cumbersome and somewhat unreadable. You could replace it with a simple increment of rxstate and a test on the two LSB for the data[n] <= rxd assignement. This is an example: (please note I wrote this code by heart; I give you no assurance it works, not even it compiles without errors) always @(posedge clk) begin if (rxstate >= 6'b100110) begin if (!rxd) rxstate <= 6'b000000; end else begin rxstate <= rxstate + 6'b1; if (rxstate[1:0] == 2'b10) data[rxstate[5:2]-1] <= rxd; end end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
your main problem is that start is being asserted roughly 9600 times a second and is NEVER stopping. Therefore, your device will forever continue transmitting. You have made no provision to stop the device after some condition or other has been fulfilled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you should only assert start when clockdiv == 0 AND [some signal which indicates you have something to transmit and want to transmit it]. Else, the cycle pasted below will keep looping forever.
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
0also serclock and start will carry equivalent values so one of them is redundant
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
here is a functioning receiver.
greeting ----------------------------------------------- module rs232_rx ( input clock, input rxd, output reg [7:0] led_g ); parameter idle = 2'b01; parameter ready = 2'b10; parameter busy = 2'b11; reg [1:0] state=idle; reg [3:0] rxd_sr=4'b1111; reg [7:0] rxsr=8'b00000000; reg [3:0] rxbitcnt; reg [11:0] rxcnt; reg [7:0] rx_data; reg rx_en = 0; parameter rcv_bit_per = 2604; //19200 Baud always @(posedge clock ) begin if(rx_en==1) led_g =rx_data; end always @(posedge clock ) begin rxd_sr = {rxd_sr[2:0], rxd}; rx_en = 0; case (state) idle: begin if(rxd_sr[3:2] == 2'b10) begin rxcnt =1302; rxbitcnt =0; state =busy; end end busy: begin if(rxbitcnt<9) begin if(rxcnt < rcv_bit_per) rxcnt =rxcnt+1; else begin rxcnt =0; rxbitcnt <=rxbitcnt+1; rxsr ={rxd_sr[2], rxsr[7:1]}; end end else state=ready; end ready: begin rx_data =rxsr; state =idle; rx_en =1; end endcase end endmodule ------------------------------------------------------------------- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WooW thank you - now it functions :)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page