EmbDev.net

Forum: FPGA, VHDL & Verilog Transmitting 12 bit by RS232 in packs of 8 bits


von Ferenc Mozes (Guest)


Attached files:

Rate this post
useful
not useful
Hi everyone!

I'm a starter in VHDL and I'm using Xilinx's Spartan 3E for some data 
conversion (A/D) and transmission to computer by RS232 protocol. The A/D 
converter has a 12 bit output but the UART controller can only transmit 
8 bits. So I was thinking that I could write a VHDL module that would 
"split" the 12 bits in two 8 bit long segments (the last 8 LSB and the 
first 4 MSB padded with zeros). Because I have to implement some digital 
filters too in a later moment, I'd like to transmit 6 packs of 8 bits to 
the UART controller, each pack after the current pack is shifted out of 
the shift register from the UART controller.
So far, I have made an entity using state machines, but it doesn't seem 
to work. I have attached the source code.

Can anybody help me to resolve this issue?

Thanks in advance!

von lkmiller (Guest)


Rate this post
useful
not useful
> use IEEE.STD_LOGIC_ARITH.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
>    signal dataCounter: STD_LOGIC_VECTOR(2 downto 0) := "000";
>                   dataCounter <= dataCounter + '1';
You should use the numeric_std and its datatypes unsigned and signed 
for doing calculations on a vector...

>      if (RFD = '1' and RFD'event) then
This will never work reliably in real world. A synchronous is defined by 
having only 1 clock source: the one and only FPGA clock.

>    sync_proc: process(CLK, RST)
>       begin
>           if (CLK'event and CLK = '1') then
>               if (RST = '1') then
1. Theres no need for the RST signal in the sensitivity list.
   The clock is the onbly signal responsible for a change in this 
process
2. What about using rising_edge() instead of the incomplete 'event and 
'1'
3. Why do you need a reset at all?

> So far, I have made an entity using state machines, but it doesn't
> seem to work.
How do you see this?
Do you run a simulation?
Or do you just try it on hardware?

von Ferenc Mozes (Guest)


Rate this post
useful
not useful
Thank you for the suggestions! I am using a reset because I have resets 
on all other entities in the whole system and in this entity the 
dataCounter needs a reset too.

Instead of
1
if (RFD = '1' and RFD'event) then
 what should I use to increment the dataCounter?

I have simulated and tried the system physically too. When I'm doing the 
simulation, the dataCounter is not incremented at all it gets "00X" then 
it goes to "XXX" after a while (after changing RFD). When trying out for 
real, there are times when the serial port receives data, and there are 
times when it gets some, but absolutely in a chaotic way.

von lkmiller (Guest)


Rate this post
useful
not useful
> Thank you for the suggestions! I am using a reset because
> I have resets on all other entities in the whole system
This is no good design practice. Read the the Xilinx whitepaper 272...

> and in this entity the dataCounter needs a reset too.
No. It doesn't. This is no logic inference and also no finally reason.
A reset does not become good because you use it everywhere.

The only thing that scores for you:
its written that way in almost every book about VHDL...
And because VHDL /= FPGA that means: most VHDL books are bad FPGA books.

However:
> I have simulated and tried the system physically too. When I'm doing the
> simulation, the dataCounter is not incremented at all it gets "00X" then
> it goes to "XXX" after a while (after changing RFD)
So go and solve the collision (='X'). Look at this:
1
:
2
: 
3
                  dataCounter <= dataCounter + '1';  --- first process
4
               end if;
5
           end if;
6
       end process; 
7
           
8
    output_dec: process(current_state)
9
       begin
10
           if (current_state = Init) then
11
               enDataCounter <= '0';
12
               dataCounter <= "000";                 --- second process
13
:
14
:
Two processes driving one signal. That must result in a collision...

> When trying out for real, there are times when the serial port
> receives data, and there are
> times when it gets some, but absolutely in a chaotic way.
How many clocks do you have in your design?
A hint: a clock signal is every signal with a 'event behind it.

>  what should I use to increment the dataCounter?
Use this state:
    next_state <= Output;
In the state Output you increment the dataCounter with the "one and 
only" FPGA CLK.

von Ferenc Mozes (Guest)


Rate this post
useful
not useful
I have solved now the existing collision.
I have only one true clock, the CLK signal which is the FPGA clock.
I will try out the configuration tomorrow in the lab, so far in ModelSim 
it works.

Thank you for the help!

von lkmiller (Guest)


Rate this post
useful
not useful
> I have only one true clock,
So, only this "true" clock has to appear with a 'event (or rising_edge 
or falling_edge) statement. Because the synthesizer will create (lokal) 
clocks for every other signal related to such a statement.

> so far in ModelSim it works.
Yes of course.
Also e.g. wait for 20 ms  works in the simulator. But (todays) theres 
no chance for this in hardware...

von Ferenc Mozes (Guest)



Rate this post
useful
not useful
I have made several tests today with the hardware configuration and my 
design doesn't work at all. In Modelsim everything just works fine, but 
there is some kind of problem when trying to send the 12 bits of the ADC 
to the RS232 controller.

I think the source of the problem is the bad synchronization of the 
splitter entity with the other entities (the ADC controller and the 
RS232 controller).
I have tested the other two entities separately and they're working just 
fine, so I'm sure that the splitter does something wrong - but I can't 
figure out what.

I have attached the files from my project, maybe you can enlighten my 
mind.
Thank you!

von lkmiller (Guest)


Rate this post
useful
not useful
Does your RS232 itself work?
Did you check to send a character from the PC, loop it back inside the 
FPGA and send it back to the PC.

I had a look after the rs232 module.
I had to sroll up and down (because its so incredibly long).
And whats that? THREE clocks... :-o
1
    if CLK = '1' and CLK'Event then
2
:
3
      if rClk = '1' and rClk'Event then
4
:
5
      if (tClk = '1' and tClk'event) then
So dont ask why your design isn't working in reality...

There is a small set of rules:
1
A VHDL desgin (particularly a starters design) must have exactly 1 clock.
2
This clock is active on the same edge always (rising or falling).
3
There is no (and specially no asynchronous and/or combinatorial) reset.
4
Every external signal must be clocked into the FPGA using 2 flipflop stages.
5
For every deviation from the rules above you must have compelling evidence 
6
and be able to eplain thoroughly why e.g. you need two clocks.
If you can sat "Yes, I've done that" to every single statement, then 
your design will work.


BTW:
Have a look for my RS232 Module. The comments are German, but you will 
have an overview almost immediately:
http://www.lothar-miller.de/s9y/categories/42-RS232

von Ferenc Mozes (Guest)


Rate this post
useful
not useful
Thank you for the kind answer!
Unfortunately I thought all over again, and concluded that serial 
communication was the worst thing I could think of, given the fact that 
the ADC works with approximately 780 KHz sampling frequency, the speed 
of the serial port was way too slow - so I need to look after another 
solution.
Anyhow, your tips were very useful, I couldn't read them in the books I 
own - and I think I'm starting to understand that simplicity is the 
keyword in digital design with FPGAs.

von lkmiller (Guest)


Rate this post
useful
not useful
> understand that simplicity is the
> keyword in digital design with FPGAs.
Yes it is.
Because the only parts you have inside the FPGA are LUTs and 
flipflops...

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.