Verilog RS232 Implementation with Varying Length of Start Bit - Page 1
Forum section: electronics / general

author: SparkFly
author_rank: Regular Contributor
timestamp: February 27, 2018, 01:04:37 pm
content: Hi all,I've been trying to implement a RS232 transmitter, following the example athttp://www.fpga4fun.com/SerialInterface3.html,however I have run into a problem and cannot seem to figure out what I am not considering.Aside from following through the tutorial, I've added my own tick at around 1400Hz to enable the Tx to start, and I suspect this might be causing the fault, but after trying to see why I cannot. My Verilog is as below:Code://module input and output,module RS232Link(clk, TxD);input clk; //48MHzoutput TxD; //UART//Baud tick (for 115200)reg[18:0] acc;always @(posedge clk)acc <= acc[17:0] + 629;wire BaudTick = acc;//Transmission start control (1400Hz)reg[15:0] startacc;always @(posedge clk)startacc <= startacc[14:0] +1;wire TxD_Start = startacc;//Bit orderreg[3:0] state;always @(posedge clk)case(state)4'b0000: if(TxD_Start) state <= 4'b0100;4'b0100: if(BaudTick) state <= 4'b1000; //start bit4'b1000: if(BaudTick) state <= 4'b1001; //bit 04'b1001: if(BaudTick) state <= 4'b1010; //bit 14'b1010: if(BaudTick) state <= 4'b1011; //bit 24'b1011: if(BaudTick) state <= 4'b1100; //bit 34'b1100: if(BaudTick) state <= 4'b1101; //bit 44'b1101: if(BaudTick) state <= 4'b1110; //bit 54'b1110: if(BaudTick) state <= 4'b1111; //bit 64'b1111: if(BaudTick) state <= 4'b0001; //bit 74'b0001: if(BaudTick) state <= 4'b0010; //stop 14'b0010: if(BaudTick) state <= 4'b0000; //stop 2default: if(BaudTick) state <= 4'b0000;endcase//Data serialisationreg muxbit;reg[7:0] TxD_data;assign TxD_data = 69;always @(state[2:0])case(state[2:0])0: muxbit <= TxD_data;1: muxbit <= TxD_data;2: muxbit <= TxD_data;3: muxbit <= TxD_data;4: muxbit <= TxD_data;5: muxbit <= TxD_data;6: muxbit <= TxD_data;7: muxbit <= TxD_data;endcase//outputassign TxD = (state<4)|(state & muxbit);endmoduleAnd here is an example of the RS232 frames I have captured, some start bits are as short as 1.6us.Again, I think the problem might be my start tick implementation, but I am likely to be wrong about that too.Any advice or suggestions would be appreciated.

author: m_t
author_rank: Contributor
timestamp: February 27, 2018, 01:39:45 pm
content: You should always simulate your design using a testbench before testing it on the FPGA! The fpga4fun examples aren't too great either, here's a much cleaner UART implementation you can use as a starting point:http://academic.csuohio.edu/chu_p/rtl/fpga_vlog_book/fpga_vlog_sample_chapter.pdf

author: langwadt
author_rank: Super Contributor
timestamp: February 27, 2018, 01:58:33 pm
content: a hint, add a state that waits for baud tick before going to start bit

author: newbrain
author_rank: Super Contributor
timestamp: February 27, 2018, 02:57:34 pm
content: I was writing a long and detailed explanation, but:Quote from: langwadt on February 27, 2018, 01:58:33 pmninjaed me, and it is good advice in two ways:Technically nails the problemNo spoon feeding!I will only add that it's not the fault of your start of transmission tick.

author: SparkFly
author_rank: Regular Contributor
timestamp: February 27, 2018, 03:54:03 pm
content: Thanks for all of your replies.m_t, yeah I know I ought to simulate first but it's too much fun to rush.) I really need to start becoming familiar with teh simulation tools out there, 100% agreed. Thanks for the link to the other Rs232 implementation.langwadt, thanks for the ideal reply! I agree with newbrain that it is much better to start with a hint and then reapproach the problem! I now have working, and I can understand why. I think for me, I'm still trying to get used to the use of clocks/ticks/whatever in Verilog, as opposed to sequential type programming. Thanks again for your hint.Also thanks newbrain for confirming that it wasnt my transmission tick causing the problem.

author: Bassman59
author_rank: Super Contributor
timestamp: February 27, 2018, 04:20:55 pm
content: Quote from: SparkFly on February 27, 2018, 01:04:37 pmJust a thought. Instead of using that output mux to drive the transmit data bit, why not use a simple shift register? Load a 9-bit shift register with the left-most bit 0 (for the start bit) followed by 8 bits of data. The TxD line is the left-most bit. Shift left, shifting in a '1' at the end of each bit time. This way, when the shifting is complete, the TxD line idles high as you expect.

author: SparkFly
author_rank: Regular Contributor
timestamp: February 27, 2018, 04:44:22 pm
content: Thanks Bassman, I'll have a go at implementing that method too.

author: m_t
author_rank: Contributor
timestamp: February 27, 2018, 08:00:27 pm
content: Quote from: SparkFly on February 27, 2018, 03:54:03 pmIf you prefer free software, you should have a look at Icarus Verilog (http://iverilog.icarus.com/) for simulation and GTKWave (http://gtkwave.sourceforge.net/) for viewing the generated waveforms.