EEVblog Electronics Community Forum

Electronics => FPGA => Topic started by: kishores on April 12, 2021, 02:48:16 pm

Title: Verilog UART doubt
Post by: kishores on April 12, 2021, 02:48:16 pm
Hi guys,
I am implementing basic communication protocols in my free time .
Regarding a UART Reciever I have a doubt .
Code: [Select]
                               S_DATA:begin
sample <= sample + 4'b1;
if(sample == 4'b1000) begin
scratch[bitindex[2:0]] <= rx;          //Statement 1
bitindex <= bitindex+4'b1;             //Statement 2
//S_STATE <= S_DATA;
end
if(bitindex == 8 && sample == 15) begin
S_STATE <= S_STOP;
//sample <= 0;
end
               end

Regarding 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
Title: Re: Verilog UART doubt
Post by: dtodorov on April 12, 2021, 02:55:55 pm
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.
Title: Re: Verilog UART doubt
Post by: BrianHG on April 12, 2021, 02:58:30 pm
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[].
Title: Re: Verilog UART doubt
Post by: SiliconWizard on April 12, 2021, 07:17:09 pm
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.
Title: Re: Verilog UART doubt
Post by: NorthGuy on April 12, 2021, 09:09:05 pm
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.
Title: Re: Verilog UART doubt
Post by: BrianHG on April 13, 2021, 01:00:08 am
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.
Yes, 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 (https://www.eevblog.com/forum/fpga/verilog-rs232-uart-and-rs232-debugger-source-code-and-educational-tutorial/msg2801388/#msg2801388)
Title: Re: Verilog UART doubt
Post by: shaheansar on April 23, 2021, 04:36:23 am
I'm a beginner to FPGAs too, and IIRC for Rx don't we just oversample? Why resynchronize instead of oversampling?