You are on page 1of 12

UART Transmitter Specifications: What it does: UART stands for universal asynchronous receiver and transmitter.

It is a protocol used in many places often including connecting terminals to computers. Well look at the transmitter part of a UART. Specifications: Data will be sent bitserially (one bit at a time) through a single line. The bit rate will be 31.25KHz. That means 31250 bits will arrive each second. (This is actually the rate for a MIDI UART communication. Computers generally run at 115.2 KHz). In each UART byte, there will be a start bit, the 8-bits of actually data, and a stop bit. This is shown below:

Start Bit Bit 0

Bit Bit Bit 1 2 3

Bit Bit Bit 4 5 6

Bit Stop 7 Bit

Note that the LSB comes first, the MSB comes last. The transmitters job is to get 8-bits of data (in parallel) and send each bit one at a time (DataOut) when it sees a Start signal. When our transmitter finishes transmitting, it tells us using a single bit output, Data_Sent. Heres the transmitters blocks I/O: Data Start CLK 8 UART Transmitter Data_Sent DataOut

The clock we will use in our circuit is a 16MHz clock. Now lets build the STD for the transmitter. Heres some pseudo-code for our STD: 1. 2. 3. Wait for Start signal Grab data (and adding a START bit and END bit for a total of 10-bits.) For 10 bits: a. Put data bit to be sent on output (DataOut) b. Keep sending it until time to send next piece of data c. Go to a. Go to 1.

4.

Here we see that there are states that wait time, and a state that counts how many times weve passed through it.

Lets figure out some numbers. We transmit data at 31.25KHz: A single clock period at 31.25KHz: 1/31.25x10^3 sec = 32 s The chip clock is run at 16MHz so it will tick many times for one bit of data: 32 s x 16 MHz = 32 x 10^-6 sec x 16 x 10^6 ticks/sec = 512 ticks For each piece of data the chip clock ticks 512 times. Lets pretend we magically have input signals that count 510, and 10. The STD therefore becomes (ignoring outputs and where the magical signals come from for now): Start Start Idle ___ 510 Grab Data

510 510 Wait 510 ___ 510

Output bit

Wait 510 10

__ 10

Passed Thru 10 times

There are many ways to do this. Come ask if you have questions about the way I did this STD. (ie: The extra wait state before Idle). Thats our main FSM. But were still missing our magical blocks. Lets design the 510 block. Heres the pseudocode for it: 1. When someone tells me to, start counting clock ticks 2. When Ive counted 510 clock ticks, output a high value. The important word here is count. We need a circuit that counts to a number then outputs 1. So the inputs and outputs are: Counted 510

Start Counting

Tell me when the clock has ticked 510 times.

Just thinking about it, that sounds like a counter with some combinational logic checking the output for the number 510. N=8 Counter Some logic which checks counter output for 509. Found 510

Reset

Planning the combinational logic block is one place you need to be careful. If you start to count from zero, and count to 510, youll actually be counting 511. So you need to actually be looking for 509. I used a counter that counts up here and I need to set it to zero when I start counting to know when Ive counted 510 ticks. So whats the logic going to look like? First lets figure out what the counter is going to look like. From now on in this class, you dont need to build counters. If you need a component that counts, draw a circuit block, with the inputs and outputs that you need, label it, and youre done with designing your counter. A little math: 510 is larger than 256 (2^8) and less than 512 (2^9) so a counter which outputs 8-bits will be able to count to 510. One with 7-bits wont. One with 10-bits is more than we need. So 8-bits sounds like the best choice. Whats the combinational logic going to look like? We could make a truth table. Weve decided that the counter has 8-bits of output so the logic block will have 8-bits of input. Hmmmmm That gives us a 256 row truth table. Doesnt sound good. But lets think what the truth table would look like if we did build it. It would have one 1 output and that would happen when the output of the counter was 509. Finding the equation for that single 1 output just involves the same steps as finding SOP from a truth table: C8 50910 = 111111012 (I think) C7 C6 And the logic would be: C7C6C5C4C3C2C1C0 C5
C4 C3 C2 C1 C0

Assuming now that you can build the other counting blocks (the count-10 block also has an ENABLE signal. Why?), we now have our magic signals. Theres something Id like you to notice here. We started with a STD. We said that itd be convenient to have a 510, and 10 count block auxiliary blocks and we built them. Now that weve built them we see that they take input: A reset signal. Where does that input come from? Well, if you remember, the reason we built those auxiliary blocks was so that theyd be convenient for the circuit that were actually trying to build, a UART transmitter. The STD we drew above, in a way, talks to these blocks. It needs to tell them when to start counting and waits for them to tell it that theyve counted to 510, or 10. In the counting block design weve done here the STD above tells the block to RESET when it wants it to start counting, then waits for the blocks I-finished-counting signal.

Putting all these blocks together and attaching with the signals that we think they need to send to each other gives us the following block diagram of the inside of the UART receiver circuit:

Data Start CLK

Data 10 510

Block that implements the STD above Block that UART Reciever implements the 510 signal Block that implements the 10 signal

EN10 Reset10 Reset510

DataOut

Data_Sent

We are still missing something. The inside of the STD block and the Data_Sent and DataOut outputs. Lets look at the DataOut output first. The UART protocol sends data serially. But often data comes in bytes. (Note that UART knows this and sends 8-bits at a time). So somehow parallel (byte) data needs to be turned into serial data. The way to do this is to use a shift register. From now on, if you hear serial-to-parallel conversion or parallel-to-serial conversion I want you to think Shift Register. Shift registers: It is a simple idea but very useful in many situations. A shift register is a chain of registers each of which has their output going into the next registers input.

In this form whatever you feed into the first flip-flop will eventually show up, in order, at the output of the last flip-flop. A FIFO. Other uses can include a multiply-by-2 or a divide-by-2 ALU. Say you have the values 0110 in the flip-flops. Thats 6. If the clock ticks, then youll have 0011 (assuming a 0 is fed into the MSB), which is 6 2=3. If you were looking at the bits in the other direction, the original number would have been 0110, which again is 6 and after the shift it would be 1100 which is 6*2=12.

Taps

D Q

D Q

D Q

Most important here, is that when you want to change parallel data to serial or serial to parallel the first thing that should pop into your mind is shift register. For serial to parallel, you just feed the number into the first flip-flop, one bit at a time, and then read it off of the taps when all of the bits have been shifted in. For parallel to serial its a little less straight forward. To carry a parallel to serial translation, a loadable shift register is the solution. The first step is to put all the bits of the parallel data into the flip-flops, parallelly, at the same time. Then, turning load off lets the data, one bit at a time, shift through to the last flip-flops output. Load Data[3] 1 D EN EN (If EN equals 0, the flip-flop will ignore the clock. Whatever is in the flip-flop will stay there. It basically turns off the shift). So Well need another block in our block diagram. The data comes into the serially and lets send it out of our block as a byte. So heres our new block diagram: DataOut Shift Register LOAD Data Start Block that implements the STD above UART Reciever Block that implements the 510 signal Block that implements the 10 signal We can see now that the STD block basically controls all the other blocks. The shift register just holds and shifts data, and the counting blocks actually do some action independently of the controlling block then tells the controlling block that its done, but they only do that when the
LOAD EN10 Reset10 Reset510 EN

Load Data[2] Q Data[1] D Q EN

Load Data[0] D EN Q

Load

D EN

Data_Sent

CLK

controlling block tells them to. The system that we will study next is just this: A block that controls the overall action of a circuit or group of circuits, and various other blocks that do some job that the system needs done. So our last job is to design the STD block, the controller. The STD we drew before was missing outputs. Lets fill those in now. This will be our output key (or legend): [LOAD, Reset510, Reset10, Enable10, Data_Sent, EN]. For example, [001010] means that LOAD=0, Reset510=0, Reset10=1, Enable10=0, Data_Sent=1, and EN=0. Keys are often used to make STD inputs and outputs easier to write out compactly. Key (or legend): ____ Start Start Start ?? [000010] ___ 510 Grab Data ?? [101000] 510 510 ___ 510 Wait 510 ?? [000000] Output Bit ?? [000001] OUTPUT: [LOAD, Reset510, Reset10, Enable10, Data_Sent, EN]

Wait 510 ?? [000000]

__ 10

Passed 10 ?? [010100]

10

Almost finished. We still need the state assignment or state value. There arent very many states but there are a lot of outputs, and most of the outputs are zero. Since we need some practice with one-hot encoding, lets encode our states as follows: Key: OUTPUT: [LOAD, Reset510, Reset10, Enable10, Data_Sent, EN]

____ Start Start Idle 000001 [000010] ___ 510 Grab Data 000010 [101000] 510 510 ___ 510 Wait 510 010000 [000000] Output Bit 000100 [000001]

Wait 510 100000 [000000]

__ 10

Passed 10 001000 [010100]

10

We can now determine the logic. Finally. If we use one-hot encoding, we dont have to use a STT to get our logic. One hot encoding means that only one of the (binary) digits is a 1 at any one time. An ID like 0001 would be considered OK in one-hot encoding but 0011 would not since there can only be one 1 in any number. Since there are 6 states and we need to be able to give each state a unique ID, we need 6-bit IDs. They would be: 000001, 000010, 000100, 001000, 010000, and 100000. We wont use a key on the arcs for inputs since each arc only watches one input, but, since there are so many outputs that need to be specified for each state, Ill use the key above to explain which output bit is which Finding next state logic when using one-hot encoding is much less work than finding logic the STT way. There will only be one 1 in the state ID so that is all you really need to pay attention to. Looking at an example: Q1: When is Idle a next state? A1: There are two cases. One is when youre already in the Idle state and Start is low. If the clock ticks, youll go right back to Idle. The other case where Idle is a next state is when youre in Wait510 (The 100000 one. Not the 010000 one) and 510 is high. If this is the case then youll go to Idle on the next clock tick also. Q2: How do you figure out the logic once you figure out Q1? A2: You know that the lowest bit of the state ID will only be 1 when youre in state Idle. Therefore you know that the next state logic for lowest bit will only equal 1 when you are moving into the Idle state. In other words, if youre in state Wait510 and 510 is high or if youre in state Idle and Start is low is the only time next states lowest bit will be 1. Changing these words directly into logic we get: In Wait510 and 510 high OR In Idle and Start low = [(PS=100000)AND(510=1)]OR[(PS=000001)AND(Start=0)]=

Since you can check what a state is by just seeing which bit of the ID is high, you can simplify this equation to: ____ NS[0] = PS[5]510 + PS[0]Start The next state equations for the rest of the bits are: NS[1] = PS[0]Start NS[2] = PS[1] + PS[4]510 NS[3] = PS[2] __ ___ NS[4] = PS[3]10 + PS[4]510 ___ NS[5] = PS[3]10 + PS[5]510 The output logic also came out quite simple. Remember that this is a Moore machine so that the output ONLY depends on the present state. From the STD you can see that LOAD is only high in the Grab Data state. So that logic is just: LOAD = PS[1] The rest of the logic also works out to be as easy to find: Data_Sent = PS[0] Reset510 = PS[3] Reset10 = PS[0] Enable10 = PS[3]

Output logic: LOAD = PS[1] Data_Sent = PS[0] Reset510 = PS[3] Reset10 = PS[0] Enable10 = PS[3]

LOAD Data_Sent Reset510 Reset8 Enable8

PS

Flip-flops for holding present state (six flip-flops since there are six bits)

The last step is to plug in the logic into your Moore machine template. Remember that this is just the logic for Next State Logic ____ the STD we built at the beginning of the handout: NS[0] = PS[5]510 + PS[0]Start Start 510 10 NS[1] = PS[0]Start NS[2] = PS[1] + PS[4]510 NS[3] = PS[2] NS[4] = PS[3]10 + PS[4]510 NS[5] = PS[3]10 + PS[5]510 6

NS

New information on the shift register: More on shift registers: Load Data[3] 1 Data[2] D3Q3 EN3 EN You may have noticed, but if we LOAD data as we did in the shift register explanation, data[0] will immediately show up on the DataOut. As soon as it is loaded, DataOut=data[0]. Then, if you look at the STD, you see that in the OutputBit state, we shift. In other words, we enable the shift register when were in that state and that means that when the clock comes, the data in flip-flop0 will be shifted out and the data in flip-flop1 will be on DataOut. This means that data[0] will only be on DataOut for one clock cycle, when we know that it needs to be there for 512 clock cycles to make the UART protocol work. So how do we fix this? The easiest way is to put something in that first flip-flop that we can throw away. This needs to be done when we load. The shift register below does that and it also guarantees that there is a 1 on the output when were finished transmitting our data (remember that when a UART is not transmitting data, there needs to be a 1 on the line). Also note that, since we transmit a start-bit and then the data starting from the LSB, we must put those values into the flip-flops in the correct order. You can see that after the dummy bit in flip-flop0 gets shifted out, the zero that had been loaded into flip-flop1 gets put on the output. This is the Start-bit. After 512 clock ticks, we Load Data[1] D2Q2 EN2 Load Data[0] D1Q1 EN1 D0Q0 EN0 DataOut Load

end up back in the output bit state, and shift in the next piece of data which will be data[0]. Then, after another 512 clock cycles, data[1] will be shifted in, all the way through data[7]. After data[7], a 1 comes. This is the stop bit. So all of this looks good. We also know that there has to be a 1 outputted when we arent transmitting data. By shifting in a 1 from the end of the shift register (see flipflop11), we will always have a 1 after the data has been shifted out.
When all data bits have been shifted, there will be a 1 on the output.
11 D11 Q11 EN11 EN

Stop-bit
Load 1 Data[7] Load Data[6] Load Data[5] Load Data[4] Load

D10 Q10 EN10

D9 Q9 EN9

D8 Q8 EN8

D7 Q7 EN7

D6 Q6 EN6

Start-bit
Load Data[3] Data[2] Load Data[1] Load Data[0] Load 0 Load

Dummy-bit
Load 1 D1 Q1 EN1 D0 Q0 EN0 DataOut

D5 Q5 EN5

D4 Q4 EN4

D3 Q3 EN3

D2 Q2 EN2

EN

New information on the Counting Loops state (The Passed Thru 10 times state): There is one state that I didnt talk about in detail. That is the Passed Thru 10 times state. The difference between this block and the 512 block is that we only want it to count up every once in a while. In other words we dont want it to count up every clock cycle, we want it to count up only when we tell it to. When we selected the flip-flops for the shift register, we knew that we didnt want it to shift every clock cycle, but only when we were in the OutputBit state. We did that with by looking for a flip-flop that had an EN (enable) input. The enable input for the flip-flop basically made that part ignore the clock. If the EN input was low, it didnt matter what was on the input and how many times the clock came, the flip-flop just sat there holding on to whatever value it had. When the EN signal became high, then the flip-flop worked just like all of the flip-flops weve seen so far; When the clock comes, it doesnt ignore it, and it grabs whatever value is on the input to the flip-flop. Now were looking at a counter. And we want the counter only to count up when we tell it to. That sounds like we need an enable on the counter too. And the enable signal would work exactly the same way the enable signal on the flip-flops worked. When the enable signal is low, the clock is ignored. In other words, if the enable signal is low, it doesnt matter how many times the clock ticks, the counter wont count up. Now, if we have a part like that, we can count up once during each loop,

then we can look at the output of the counter to see how many times weve passed through the loop. And, in the same way we did for the 512 block, we can put an AND gate on the output of the counter to give us a high signal when the counter is outputting 10 (in this case).

You might also like