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.
Use a single 100 MHz (10 ns) clock for all circuits.
Here are the key block signals:
- 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[8: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 | | | Saturat | | | | |
| | ^ | | ^ | | ^ | |
+----------+ | +---------+ | +---------+ | +----+-----+
| | | |
| | | |
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 accompanying
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 4x upsampling
whereas your design must do only 2x 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.
For the upsampling and low-pass filtering, round the output by
adding a half LSB and truncating.
Choose the point where you round 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).
Also add
enough sign extension
bits so that
sig100
can never overflow under any circumstances.
Force signals to specific values with verilog commands force
and release in the testbench rather than temporarily changing
your hardware.
Build the upsampler with the merged Nyquist filter + 2x upsampler
we discussed in class.
The cdma.m matlab file performs upsampling
by 2x, shows spectral results, and may be helpful as a starting point.
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 (use provided wide 4:2 submodules) plus one CPA
(may be smallest).
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.
Compressor
Instead of saturating the final output, build a compressor with the
same characteristics as the one shown in this matlab plot and code:
PrintOn = 0;
xvals = [-64:63];
xsat = 48;
for l=xvals,
if l<-xsat
b(l+65) = -31;
elseif l < 0
b(l+65) = 31*sin((l/xsat)*(pi/2));
elseif l < xsat
b(l+65) = 31*sin((l/xsat)*(pi/2));
else
b(l+65) = +31;
end
end
figure(1);clf;
plot(xvals, b);
hold on;
grid on;
%plot([-24:24], [-24:24]*(pi/2), 'r'); % not slope=+1 line
xlabel('Input value');
ylabel('Output value');
title('Compressor function');
if (PrintOn) print -dtiff compressor.tiff; end
Designing, Testing, and Grading [175 pts + 0-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.
- [0-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