Serial Transmitter Transcript

Greetings, I'm Ben Cooper, uml2hdl product manager and I'm going to demonstrate how to use uml2hdl to design and implement an asynchronous serial transmitter.  This is a standard design we're all familiar with, so it provides a good reference to demonstrate the speed and efficiency of the uml2hdl design flow.
The design file named "SerialTx" is included with the uml2hdl distribution. You can open it from the Files-> Open Example menu command and use it as a reference if you like.  
Just for the record the serial format of the transmitter will be one start bit, one stop bit, and an odd parity bit.e design file named "SerialTx" is included with the uml2hdl distribution. You can open it from the Files-> Open Example menu command and use it as a reference if you like.  
Just for the record the serial format of the transmitter will be one start bit, one stop bit, and an odd parity bit.
Pad Stack
We'll start in the Document Properties Editor where we set up the design parameters.  We ensure that the correct HDL language is specified, and, if necessary, setup the output directory for the generated HDL.
Next we'll specify the pad stack of IO pins.
First we'll enter the input pads, so we'll move down to the Input section.  Of course we'll need a clock and a reset input, so click the "ADD" button, and the New Input Port Dialog appears, then we enter TxClk.  It's a single bit signal so no width needs to be entered.  Select OK and we're ready to start again with TxRst, the reset input. Again, enter the name then click OK. 
Now we're ready to add the transmit data input pads.  We ADD TxDin, the parallel data input, which has a width of eight.  The drop down menu shows that there are no constants defined yet, so we select ADD.  The Add constant dialog opens, and we enter the constant's name, BITS_PER_BYTE, and a value of 8. The last input is the TxDWr signal that schedules the write of transmit data.Now we can enter the Output Pads.  First, of course, is TxD the serial data output.  We also will need TxRdy, the signal that indicates that the transmitter is available to accept TxDin parallel data input.  This entry completes the pad stack.
Now we can begin the general uml2hdl design flow by instantiating the necessary UML Objects.  We'll certainly need a shift register to convert parallel data to serial, so we'll start there.  We'll also need to count the bits in a baud, so we'll instantiate a counter.  And we'll need a parity generator so we instantiate a parity object. 
That should be all of the objects we'll need so we move on to the next step - configuring the objects.  The counter is straightforward so let's start there.  It's important to give all objects a functional name, so let's name it BaudCtr.  A baud will include 8 data bits plus the start, stop, and parity bits for a total of 11, so we need a four bit counter with modulus of 11.  We define new constants as we assign four to the counter width and BITS_PER_BAUD, or 11 to the counter modulus. <PAUSE>
Now we could use a modulus 11 up counter and use it's terminal count to flag the end of a baud.   However, this would require that we initially load the counter with a count of 11 on the system reset.  If we use a modulus 11 down counter, the zero count generates the terminal count, and we can use a standard clear to set this value on reset.  This is simpler to implement, so it's what we'll do.  We specify a down counter, with a synchronous clear, a count enable, and a combinational terminal count. <PAUSE>
Now let's move to the parity generator.  This object can be configured as a pairity generator or checker, but the default is a generator so this does not need to be changed.  Odd parity is also the default so this does not need to be changed either.  We need to set the width to BITS_PER_BYTE, but then we can move on to the shift register. <PAUSE>
The async protocol specifies that a start bit is low or zero, and a stop bit is high or one, and the high mark level is maintained when no data is being transferred.  The transmit data least significant bit is shifted out first, after the start bit.  So we need a shift register that shifts down or right, with a synchronous parallel load .  We also need to set all bits high on a system reset, so we'll need a synchronous set input.
At first glance it appears that the width of the shift register should be 11 bits, the number of bits in a baud.  However, we need to shift ones into the msb of the shift register to ensure that the line is held at a high mark when no data is being transmitted.  This also sets the eleventh bit high, even if it is not registered in the shift register, so the shift register only needs to be ten bits wide.  We specify the width of the shift register as one less than the BITS_PER_BAUD, a new constant called BITS_PER_BAUD_M1 with a value of 10. <PAUSE>
Now all the objects are configured, so we're ready to add the link expressions.
Let's start with the shift register by selecting it, so it's properties editor appears in the properties panel.  It's clock input should be connected to the TxClk input pad so we click on Clock input, then the ellipsis to assign a link.  The Expression Editor appears and enables us to enter the link expression. In the outputs tab there is a tree of the document.  Expanding the pads node reveals the TxClk pad.  Double click on this node and the name appears in the expression.  That's all that's needed for this expression, so click OK to enter this link.
Now we can repeat for the SyncSet input, and we link to the TxReset pad, so the contents of the shift register are forced to a mark on reset.  The SyncLoad input needs to be linked to the TxDWr input pad so the register is loaded when data is written to the the transmitter.  The shift register shifts continuously so the MSB input needs to be set high so the mark output is set when the transmitter is inactive.  This can be done from the constants tab as we're doing, or you could just type a literal constant from the keyboard.
The last input for the shift register is the 10 bit parallel data input, so we select this input and then the expression editor.   This register needs to be loaded with the parity in the most significant bit, then the data byte, and finally the zero start bit in the least significant bit.  We use a concatenation for this expression and enter the parity, transmit data, and the zero bit with the concatenation separator. 
Now we've assigned expressions to all the shift register inputs.  Notice the red UNASSIGNED flags on the Shift Register symbol have been replaced by the assigned expressions. <PAUSE>
Now let's enter the links for Baud Counter.  The counter's clock is linked to the TxClk input pad, just like the shift register, and it's clear is also linked to the TxRst pad.  The count enable needs to go active when Transmit Data is written by TxDWr, and should stay enabled while it is counting, but counting should be disabled when it returns to the zero terminal count.  So for the count enable input we enter the expression TxDWr OR NOT Terminal Count.  And this completes linking the baud counter. <PAUSE>
Now the only object left to link is the Parity Generator. The only input is the data, and this clearly should be assigned to the input transmit data, TxD.

The last step is to assign link expressions to the output pads, so we move to the document properties editor outputs section.  Select TxD, then the ellipsis to display the Edit Output Dialog.  Then select the ellipsis for the Out Link, which brings up the Expression Editor.  Double click on the LSB output of the shift register to link the shift register output to this output pad.  Now we also need to assign a link to TxRdy, so we follow the same process to get to the Expression Editor.  Baud Counter's Terminal Count is high when the counter is at zero and no data is being transmitted, so this signal can be used as the transmitter ready signal.  We link this output directly to the TxReady output pad by double clicking on the Baud Counter terminal count on the output tab. 



Now all the input links have been assigned,  so we're ready to generate our HDL souce code....
To view the HDL for the current diagram, just select the HDL tab - and there it is - the compiler ready source code for the current diagram.
To generate the HDL files for the complete document just select Generate from the file menu or click the gear icon. 
That's it..  you have just implemented an asynchronous transmitter in under 10 minutes...
If you will spend another few minutes with our asynchronous receiver screencast I'll show you some short-cuts that can speed up your uml2hdl designs even more...