Hi friends, we all know how easier it is for anyone to ask
you to deliver a SYNTHESIZABLE RTL based
on any C/MATLAB etc. and you are stuck with a dilemma in guessing where to
begin with. So in this post we will be laying down some fundamentals along with
examples that may help you in getting it done right and easy. We have divided
this tutorial into a set of stages each of which targets a specific aspect of
RTL coding/design. These stages start from black box to detailed architecture
level models as well extended but not limited to synthesizable RTL as well as
gate level designs.
Our of the examples will include:
·
Basic digital designs: Adders, ALU, Comparators,
Counters, Multipliers etc.
·
Memory Models : ROMs, RAMs, 2-port memories, single
port memories.
·
FSM Designs : Mealy, Moore, One-hot.
·
Processor design : RISC, CISC.
·
ASIC Cores : FFT processors, DWT
processors, FIRs Filters, Convolutors, Image/video codecs.
Stage 1 : Black Box and
Block Diagrams
Before starting with examples and coding methods, let us
first define the basic steps that you should take for implementing your code
especially if you’re a novice.
1. Get the Black Box:
Break the code as black box entity that
takes something as an input and outputs something.
Example:
Suppose you want to make a digital clock.
Then it can simply be treated as a black box that simply outputs the time with
some control (for adjusting time) and reference signal (a digital oscillator
clock) as inputs.
2. Pen is Mightier
than Code:
The next step is to get the hang of the
functionality that this black box is supposed to do. Take the function itself
that the code is meant for and use it on a very simple test case but rather
than using the code use a pen and paper solve it instead. This is the only way
you will understand the code and identify your true problem statement
Example:
Consider the same clock problem as above.
How will you write the same function as the clock on a paper? Simple:
·
Consider the current time as A (hours : minutes :
seconds)
·
Write three variables HR=0 MIN= 0 and SEC= 0.
·
Now keep checking your reference watch/clock and
after each second/tick (take 5 if you can’t write quick: P ) add 1 (or 5 if you
followed the previous advice) to SEC.
·
Now by doing so a point will come when after
adding SEC = 60, at this instance add 1 to MIN and change SEC=0.
·
Do the same for HR when MIN=60.
·
For getting the output time simply add the reference
time A to the calculated time HR:MIN:SEC ( be careful while adding time it’s
not 0-100 but 0-60)
·
And there you go the clock is working on paper.
3. Break the Black
Box:
So far you should have got a hang on things
regarding what and how the function is supposed to do things. The next step is
to break this functionality into smaller and simpler groups and the best way to
this is to take inspiration from your own rough work. Refer to the paper on
which you solved the problem itself and identify each type of secondary
function you had to do/use in order to write stuff on that paper. This helps
you in creating solutions for multiple simpler problems instead of a complex
one. But enough said, this is a statement we’ve all heard people say but what they
ever tell us about is how to do it exactly. So here’s what you have to do.
Example:
The first thing that you will notice on the
paper is the very first column titled tick. This column is simply used to track
the number of ticks that have occurred after reference time A. In digital
domain you can simply realize this by using a synchronous up-counter operating
at 1Hz clock frequency (every 1second the counter increments by 1).
So
there you have the very first sub-block of your system i.e. an up-counter block
A. Leave the counter specifications like size and reset limits for now, we
shall discuss this at a later stage.
The next 3 columns show 3 internal
variables that you use for keeping track of time count. In digital domain
variables can simply be realized by using registers as they can be loaded as
well as read. In addition, each of these variables is always incremented by 1
and resets to 0 when its value reaches 60 (except for HR which may be limited
to 12/24).
Thus they can be modeled using three
registered variables along with an adder (adds +1) which is the second
sub-block inside the black box name block B.
The 5th column A is simply a
reference variable and it never changes, so you can simply use it as a direct
input. The last variable is simply an added version of previous 4 columns and
hence can be realized using simple adders as a block C. And this completes the
breaking of the black box as follows:
4. Link the Blocks:
After identifying the key sub-blocks of
your concerned design/code/function the next step is to link the logical
exchange of info amongst these blocks as well as the external world. To do so
identify the dependency of each block and simply use arrows to denote those
dependencies. This will help us in understanding the inputs and outputs of each
of these sub-blocks and thus understand the actual flow of information.
Example:
Let us start with block A. It is an
up-counter and an up-counter primarily depends on the reference clock that
keeps on triggering it. Thus block A only has a dependency on external
reference clock signal.
Block B has three registers which are
either added one or reset to zero. The addition however is driven by certain
conditions from both the counter values as well as register values themselves.
Thus the dependency of adder unit inside block B is only the register outputs
while the registers have three dependencies, first from the output of adders,
the second from the up-counter and the third from the other register like HR is
dependent on MIN, MIN is dependent on SEC and SEC is dependent on
up-counter.
Block C is rather a much simpler block that
only adds the three registers of block B to input reference time. Thus it only
has a dependency on input reference time and three block B registers. The
important thing about this block though is that the output of this block is in
fact the output result itself.
5. The Missing Link:
At this point you should have more or less
identified all the major data processing requirements of your design. However,
the key entity missing in these links is the control and synchronization block.
This is the block that decides the what, when and how the data flows across all
these connection links shown above so that the desired functionality is obtained.
The concept of a Finite state machine or
FSM is one of the most commonly used techniques to model this control block.
The key idea behind FSM is that at any moment each section the design will be
doing some work. However, this work will always be of repetitive nature and
sequence of work performed will also be of finite order like a counting
sequence with limited upper value which goes like 1,2,3,…9,1,2,3,..8, 9, 1 &
so on.
We will discuss the concept of FSM in more
details later but for now let us assume that this FSM block is the main control
unit that synchronizes each and every block of your design. The inputs to this
block will be the output of each block and/or input that is required for
determining the next sequence of action and the outputs are function enabling
signals like a memory chip-select or reset signal. The FSM is also similar to a
counter and hence this will also use a reference clock for its operation.
And there you have it
folks, from black box to top level block diagram for your RTL right from the
scratch.