This problem consists of the design, implementation, and synthesis
of a CDMA transmit path.
Register all inputs before using them and register all outputs
before they exit the block.
Here are the key block signals:
- input clock
Use a single 100 MHz (10 ns) clock for all circuits
(do not divide the clock to a lower frequency).
Clock signals may be tied only to clock inputs on flip-flops.
- input reset
Synchronous reset, asserted high.
- input data[6:0]
Data input, one bit for each code or "user."
This specific design supports only seven users.
- input comp_on
Enables compressor function.
"sigsat" 6 LSBs
passes directly to "out" when comp_on == 0.
- output out[5:0]
2's complement output waveform,
100 MSamples/sec.
You may add other signals as needed (within reason, it may be helpful to have
some sort of handshaking for read input data) to communicate
with interfacing circuits.
+----------+ +---------+ +---------+ +----------+
| | | | | | | |
reset | Code | | | | | | |
-------| geners | 4 | Upsamp2 | ? | | 7 | | 6
data | Add33 |--/--| LowPass |--/--| Saturat |--/--|Compressor|--/--> out
---/---| Control | | filter | | | | |
7 | | | | | | | |
| | ^ | | ^ | | ^ | |
+----------+ | +---------+ | +---------+ | +----+-----+
| | | |
| | | |
50 MSamples/sec | | |
sig50[3:0] sig100 sigsat comp_on
Baseband Transmitter
This project uses orthogonal length-8 Walsh codes
to modulate data for seven users.
The
cdma.m matlab file generates the Walsh codes, modulates
data onto the codes, and assembles the transmit symbols.
Your system should perform the exact same operations bit-for-bit.
The cdma.m file is meant as an example and performs ↑2 and ↑4
upsampling whereas your design must do only ↑2 upsampling.
Use the 33-input adder you designed for homework 1.
Disable unused inputs by setting half of them to 1 and the other half to 0.
Tie these unused inputs off in your synthesized verilog module (not your
external testing module) and DC should optimize away some circuits for you.
Upsampling and Filtering
Upsample the sig50 signal by 2 times and filter out images
produced by the upsampling. Build the upsampler with the merged
Nyquist filter + ↑2 upsampler we discussed in class. Add enough
sign extension bits so that sig100 can never overflow under
any circumstances.
The output must have less than 2 dB attenuation from 0 to
0.40 π, and at least 28 dB attenuation from 0.60 π
to π, according to freqz.
For the upsampling and low-pass filtering, round the output by
adding a half LSB and truncating.
The point of rounding is set by the requirement that the Saturator's
output must be 7 bits wide, and the point of saturation determined during
the design of the Saturator.
Implement the filter by either:
1) "+ (in * coeffx)" for each filter tap.
2) "+ (in << 4)" for each partial product (probably smaller), or
3) using rows of 4:2 adders,
3:2 adders,
(feel free to use provided wide submodules)
or half adders,
plus one CPA (may be smallest).
Saturator
Choose the point where you
round saturate
by setting
sig50 to a constant +7 or -7, and making sure sigsat
has all its bits with "good" data and is not saturated (one
sign-extension bit or zero repeated-MSBs).
This implies that if the value of the filter's output were doubled from
+7 or -7, then the Saturator would surely saturate.
Force signals to specific values with verilog commands force
and release in the testbench rather than temporarily changing
your hardware.
Compressor
Instead of saturating the final output, build a compressor with the
same characteristics as the one shown in this matlab plot which was
made by compressor.m:
Designing, Testing, and Grading [175 pts + 35-75 pts]
The overall goal of the project is to design a working system with low area
(low power). In order of importance, you should:
- design components and get verilog working
- write bit-accurate matlab
- get synthesis working
- meet 10ns clock cycle time without timing violations (negative slack)
- minimize area (meaningless without meeting timing)
For parts below regarding designing and drawing...
Include pipeline stages and word widths in bits.
There must be enough detail so that the exact functional
operation of the block can be determined by someone with a
reasonable knowledge of what simple blocks do (e.g., "block generates
walsh code #2", or "add33 adder") and your diagram and explanation.
Include details of the datapath and control.
For parts below regarding bit-accurate models and testing...
Keep bit-accurate models as simple as possible to make debug easier
(i.e., don't write your verilog first and then force matlab to
be the same). Use floor(signal+0.5) for rounding.
For full-credit, compare at least 25 symbols.
You may test within a block-level simulation or within a larger simulation.
It may be easiest to generate random inputs in verilog, write out
input and output from verilog into a file in a format matlab can
easily read (such as, in(1)=5; in(2)=-2; ... on different lines),
and do the comparison inside matlab.
You may have to neglect samples near the beginning and end
of your simulations to get 100% matching; this is ok.
- a) [10 pts] Design and draw a block diagram of the
baseband transmitter including details of the code generators,
adder, and control.
- [25 pts]
Write verilog and clearly show that it
matches the bit-accurate matlab.
- b) [10 pts] Design and draw a block diagram of the
upsampling and filter circuits.
- [25 pts]
Write verilog and a bit-accurate matlab model and clearly
show that they match.
- [10 pts]
Show the freqz(); plot for your filter
described above with axis ([...]); set to clearly see the
important range.
- [25 pts]
Show a verilog waveform of the input and output for the filter alone
using the following input:
- maximum magnitude negative impulse input
- c) [10 pts] Design and draw a block diagram of the
saturation and compressor circuits.
- d) [35 pts] Show three waveforms in matlab from your verilog simulation
of the entire system with random inputs:
1) compressor off,
2) compressor on, and
3) the difference.
- e) [25 pts] Synthesize the entire system.
Turn in listings given below.
- [35-75 pts] Smaller area receives more points.
Must be fully functional, with working and tested bit-accurate
matlab, and clean synthesis (no errors or serious warnings).
Don't modify the synthesis script except for functional purposes
(e.g., to change or add source file names). There are many
knobs to enhance synthesis results but that's not the focus of
this homework. If you do improve the script, please let me know
and I'll add it to the base script.
Run your compile with "medium" effort.
Turn in paper copies of the following. Print in a way that is
clear and easy to understand but conserves paper (multiple files per
page, 8 or 9 point font, multiple columns).
Edit sections with many repeating lines so they have only a few lines
and replace with the comment: <many lines removed> .
- dc_compile (or equivalent)
- *.area file
- *.log file; use something like dc_shell -f dc_compile
| tee prac.log as shown on the DC tutorial page.
Edit "Beginning Delay Optimization Phase"
and "Beginning Area-Recovery Phase" sections.
- *.tim file; first (longest) path only
- source verilog files
- test verilog files
- source matlab files
Possibly-helpful suggestions
- Work on a block at a time, especially when doing bit-accurate
testing. You'll go crazy trying to debug a downstream block if
an upstream one is causing the trouble.
- For bit-accurate testing, you can generate input data from
either matlab or verilog. I think it's a little easier to
generate input data in verilog and then print both input and
output to a matlab-readable file
and test and
compare in matlab. You may find it handy to declare variables as
signed in verilog and print them using $fwrite
so both positive and negative numbers print correctly.
- Use the matlab function
difff.m
to easily compare two signals.
- The file
tb.vt, and
cdma.v
may give you a helpful start with the testbench.
- When debugging filters, start with an impulse-response input. This
likely won't be a [0, 0, 0, 0, 1, 0, 0, 0, 0] that you normally think
of as an impulse response, but the "1" should be the largest
input possible which may be a "-8", "+4", or "+7". It will be
easier to see what is going on if you use a power-of-2 input. This is
where a detailed block diagram is going to save you a headache. Think
carefully about what you expect on the output.
- Make sure you design your filters so the output can fully represent
a worst-case input, which is going
to have two versions: both are full-scale and one's signs match the
filter's coefficient's signs and the other worst-case input has the
opposite signs of the filter's coefficients.
Ex: [+7, 0, -8, 0, +7, 0, -8, 0, +7]
and [-8, 0, +7, 0, -8, 0, +7, 0, -8].
- As a rule, register all inputs into your top level to give those
signals a full clock cycle to work inside your block before they
have to be registered again. To be extra conservative, I gave you
a small 0.50ns setup window, but the down side is that those paths
will likely show up at the top of your timing reports. So go ahead
and change input_setup to 6000 in your dc_compile file.
I've made the change to the version on the web. input_setup =
6000