Verilog UART doubt - Page 1
Forum section: electronics / general

author: kishores
author_rank: Newbie
timestamp: April 12, 2021, 02:48:16 pm
content: Hi guys,I am implementing basic communication protocols in my free time .Regarding a UART Reciever I have a doubt .Code:S_DATA:beginsample <= sample + 4'b1;if(sample == 4'b1000) beginscratch[bitindex[2:0]] <= rx; //Statement 1bitindex <= bitindex+4'b1; //Statement 2//S_STATE <= S_DATA;endif(bitindex == 8 && sample == 15) beginS_STATE <= S_STOP;//sample <= 0;endendRegarding statement 1 and 2 , what is the guarantee that for Statement 1 bitindex[2:0] will be read before increment in Statement 2 ?I understand that both statements will be run on same clock cycle but why is there no race between Statement 1 and 2. Am I missing something basic in Verilog?Thanks in advance

author: dtodorov
author_rank: Contributor
timestamp: April 12, 2021, 02:55:55 pm
content: No races will occur, since you are using non-blocking assignments.In other words, during the procedural code execution, the values of expression members would be as if no update has occurred yet.

author: BrianHG
author_rank: Super Contributor
timestamp: April 12, 2021, 02:58:30 pm
content: They are both run at the same time, however, think about it this way.When the clock rises (assuming you have posedge clk), the new rx data is loaded and and the bitindex is incremented. However, the new bit-index and new data loaded into register scratch[] will not change for another (really dummy example) 5ns (if your FMAX is 200MHz). So, it is impossible for the new loaded bitindex to travel back in time to 5ns earlier to affect where rx will be put into register scratch[].Even if your FPGA has a 100GHz maximum frequency, when the clock toggles, the new incremented bitindex would need to travel 10ps backwards in time to affect where rx goes into register scratch[].

author: SiliconWizard
author_rank: Super Contributor
timestamp: April 12, 2021, 07:17:09 pm
content: That's not a question specific to any UART implemention, but just a very general - and basic - HDL question.See above - but basically, you can consider that any signal will hold its current value at each clock cycle, and will have its new value at the next cycle. Of course timings are analyzed during implementation to check that it holds true, but from a language POV, that is guaranteed.Side note: UART deal with - by definition - asynchronous inputs.You should definitely resynchronize the 'RX' signal to your own clock and sample the synchronized signal instead. Otherwise you're in for a rough ride.

author: NorthGuy
author_rank: Super Contributor
timestamp: April 12, 2021, 09:09:05 pm
content: By the time the clock edge comes, all these things have already been calculated. The clock edge simply latches the results of these calculations into flops. All registers change at once at the clock edge. Flops then hold their value, and will do so until the next clock edge. In the time between the edges, the combinatorial logic uses signals produced by flops to produce the values for the next clock edge.For UART: instead of array, use shift register - it's much easier with hardware.

author: BrianHG
author_rank: Super Contributor
timestamp: April 13, 2021, 01:00:08 am
content: Quote from: SiliconWizard on April 12, 2021, 07:17:09 pmYes, this looks like a learning how HDL works type of exercise for the OP. However, if you want a real proper UART, not only do you need to sync your 'RX' and center optimize the sampling clock, but when interfacing with PC's RS232 ports, if you want to transmit at the same time, you need to sync your TX out to the RX coming in.So, I would say do not goto this thread which shows you how to do both at the same time:https://www.eevblog.com/forum/fpga/verilog-rs232-uart-and-rs232-debugger-source-code-and-educational-tutorial/msg2801388/#msg2801388

author: shaheansar
author_rank: Contributor
timestamp: April 23, 2021, 04:36:23 am
content: I'm a beginner to FPGAs too, and IIRC for Rx don't we just oversample? Why resynchronize instead of oversampling?