Sunday, November 30, 2014

Project Update

Since the previous post this is what I have worked on:
  1. Modifying the UVM components to be more generalized and flexible 
  2. Found a data corruption bug in the FIR filtering block
  3. Found an integration bug where I had a typo on a port name

Modifying UVCs

Improving the "UVCs" has taken much longer than I anticipated. The DUT has different data widths for the input signals vs the output signals. At first I thought I could simply cast a parameterized interface and pass that to the testbench using uvm_config_db. I quickly learned that this wasn't going to work. Someone else on the internet had exactly the same problem. I used solution #2 as suggested in that form. I needed to parameterize the low-level testbench components that use the virtual interface. After making the changes and fixing the bugs I introduced in the process it seems to work well. Not only did monitor and driver components need to be modified but the sequence items needed to be changed to use dynamic arrays to be more flexible.

Previously the sample interface agent was well developed to be a SLAVE device because that was the only requirement for the previous DUT. The current DUT has a SLAVE and MASTER interface. Some development effort was required to get that aspect operational.

What's Next?

I was debugging a DUT bug in the filtering sub-block but time ran out. I will pick it up next weekend. I think I have done the majority of the ground work needed so i can start working on the scoreboard next weekend. Lets see how it goes!



Sunday, November 16, 2014

Project Update

It has been a few weeks since I made a record of my progress. Since the last update I have completed the RTL for the "interpolation filter" block and started developing the verification environment.

A high level overview / update

  • Complete:
    • RTL for the sub-blocks
      • Zero Stuffing
      • Filtering
      • Decimation
      • Rounding/Scaling
    • Integrated the sub-blocks into a top level "interpolation filter" block
  • In progress:
    • Verification Environment:
      • Leveraging common code from the "ADC to samples" block
      • Generalizing interfaces and low level verification components for different sample bit-widths
      • Conceptualizing a few useful test cases.
    • Selecting filter coefficients that do interpolation and low pass filtering. I'm planing to use MATLAB to help on this one.
    • Need to clean up the documentation of the top level block and the low level sub-blocks

This block is a bit boring so far. Writing the RTL and starting the verification environment has been a bit of a grind. I'm still very excited about the scoreboard aspect of this block. The scoreboard will require me to learn DPI and do some fixed point math fun in C.

Sunday, October 26, 2014

Project Update

This weekend I started working on the re-sampling block. The "zeroth draft" of the RTL for the zero stuffing block is complete. I will also share the pre-first draft of the spec for the block to show the design intent. This weekend I didn't get a chance to start the RTL for the  filtering block but I have been putting in a lot of mental effort, visualizing how the logic should work (inferred hw multipliers etc). I'm leaving the filtering block for next weekend.


interpolation_filter.png
The Block Diagram for the re-sampling block

Zero Stuffing

Module
Zero Stuffing
Inputs
  • sample_valid_i : active high signal that the slave device uses to determine when the value on the sample bus is valid
  • [11:0] sample_i : the sample data to be read by the slave device
  • sample_rdy_filter_to_zs : active high signal that the master device uses to determine if the slave is ready to receive a sample
  • sample_ack_filter_to_zs : active high signal that the master device uses to determine if the slave successfully received the sample
  • rst : synchronous, active high reset signal
  • en : synchronous, active high enable signal
  • clk : system clock
Outputs
  • sample_rdy_i : active high signal that the slave device uses to indicate it is ready to receive a sample
  • sample_ack_i : active high signal that the slave device uses to indicate that the sample has been successfully received
  • sample_valid_zs_to_filter : active high signal that the master device uses to indicate that the signal on the sample bus is valid
  • [11:0] sample_zs_to_filter : the sample data written by the master devices
Functionality
To achieve an interpolation factor of 6 the first step is zero stuffing. 5 zero samples are appended for every original sample.
<write up>


Filtering

Module
Filtering
Inputs
  • sample_valid_zs_to_filter : active high signal that the slave device uses to determine when the value on the sample bus is valid
  • [11:0] sample_zs_to_filter : the sample data to be read by the slave device
  • sample_rdy_dec_to_filter : active high signal that the master device uses to determine if the slave is ready to receive a sample
  • sample_ack_dec_to_filter : active high signal that the master device uses to determine if the slave successfully received the sample
  • rst : synchronous, active high reset signal
  • en : synchronous, active high enable signal
  • clk : system clock
Outputs
  • sample_rdy_filter_to_zs : active high signal that the slave device uses to indicate it is ready to receive a sample
  • sample_ack_filter_to_zs : active high signal that the slave device uses to indicate that the sample has been successfully received
  • sample_valid_filter_to_dec : active high signal that the master device uses to indicate that the signal on the sample bus is valid
  • [35:0] sample_filter_to_dec : the sample data written by the master devices
Functionality
The filtering block has two roles:
  1. Interpolation filtering
  2. Lowpass filtering to prevent aliasing before decimation
<write up>

Decimation

Module
Decimation
Inputs
  • sample_valid_filter_to_dec : active high signal that the slave device uses to determine when the value on the sample bus is valid
  • [35:0] sample_filter_to_dec : the sample data to be read by the slave device
  • sample_rdy_rs_to_dec : active high signal that the master device uses to determine if the slave is ready to receive a sample
  • sample_ack_rs_to_dec : active high signal that the master device uses to determine if the slave successfully received the sample
  • rst : synchronous, active high reset signal
  • en : synchronous, active high enable signal
  • clk : system clock
Outputs
  • sample_rdy_dec_to_filter : active high signal that the slave device uses to indicate it is ready to receive a sample
  • sample_ack_dec_to_filter : active high signal that the slave device uses to indicate that the sample has been successfully received
  • sample_valid_dec_to_rs : active high signal that the master device uses to indicate that the signal on the sample bus is valid
  • [35:0] sample_dec_to_rs : the sample data written by the master devices
Functionality
The decimation block reduces the sampling rate to 48Ksps. The decimation factor is 25. Only 1 in 25 samples are kept, the other 24 samples are dropped.
<write up>


Rounding / Scaling

Module
Rounding / Scaling
Inputs
  • sample_valid_dec_to_rs : active high signal that the slave device uses to determine when the value on the sample bus is valid
  • [35:0] sample_dec_to_rs : the sample data to be read by the slave device
  • sample_rdy_o : active high signal that the master device uses to determine if the slave is ready to receive a sample
  • sample_ack_o : active high signal that the master device uses to determine if the slave successfully received the sample
  • rst : synchronous, active high reset signal
  • en : synchronous, active high enable signal
  • clk : system clock
Outputs
  • sample_rdy_rs_to_dec : active high signal that the slave device uses to indicate it is ready to receive a sample
  • sample_ack_rs_to_dec : active high signal that the slave device uses to indicate that the sample has been successfully received
  • sample_valid_o : active high signal that the master device uses to indicate that the signal on the sample bus is valid
  • [17:0] sample_o : the sample data written by the master devices
Functionality
The purpose of the round / scaling block is to reduce the bit width of the samples from 36 bits down to 18 bits. The goal is to minimize the loss of information (non audible modifications are desired)
<write up>

Sunday, October 19, 2014

Pitch Correction Project Update - 10/19

I have to apologize in advance because I don't spend enough time putting these posts together. I want to tell a clear story but at the same time - every minute spent on the post is a minute not spent on the project.

ADC Controller Off By 1 issue

 I fixed the off by 1 issue. The root cause was because I started decrementing the index counter 1 cycle too early. As a work around I simply had a local chip select signal that was delayed by 1 clock cycle. When the decrement logic was triggered by the delayed signal things began to look better.

As I was fixing the off by 1 issue I found another issue where I wasn't recording the LSB of the sample before sending it out to the next section of the design. I didn't even bother trying to fix this because I realized I needed to rewrite the block. More details in the next section

ADC Controller Rewrite

When writing the RTL for the ADC controller I assumed could get desired sample rate by using the "single shot" method. In the single shot method the chip select signal is only asserted for a single sample retrieval. As I was debugging I realized that consecutive "single shots" were not going to give the desired sample rate. I would have to use the ADC in it continuous sampling mode. The first implementation was a mess because it was my RTL coding refresher. I scrapped the first implementation and recoded it. This time it only took fraction of the time to code the block and it worked after fixing a few basic typos. Nice!

Scoreboard for ADC_to_Samples block

On the verification side of the project I completed the scoreboard for the ADC_to_samples block. I have been working on the verification infrastructure for this block for a couple of weeks. Now the first alpha verification environment is complete and it seems to be working.

Up Next: Interpolation filter

Now that that ADC_to_samples block is "complete" I can move to the next block in the project. I'm taking a simple strategy of following the data path. The next next block is the interpolation filter. I included an interpolation filter to try to compensate for the poor ADC resolution (12 bits). I hope that I can sample at the ADC max sample rate (200 ksps) and use the interpolation filter for sample smoothing and moving down to 44.1ksps.

This block should be a lot more interesting than the adc_to_samples  block because it will force me to refresh on fixed point arithmetic, filter structures and the verification side will be far more involved WRT the scoreboard.

The only spec I have for the block is at the interface level so I need to begin the functional decomposition process until I have more manageable design components.

Lets see how it goes!

Sunday, October 12, 2014

Pitch Correction Project Update

I haven't made much progress since the last post.

  • Resolved blocking issue WRT to the simulator
  • collector and monitor complete for the adc bus and the sample_iface bus
  • started tracing the sample_in != sample_out issue

Taking a look at sample_in != sample_out

Sample going into the DUT (adc controller) vs the sample coming out

This image shows the basic error. The sample being pulled from the ADC is 0xe95 but the sample going out is 0x74A.

Individual signals showing "off by 1" error
 After looking at the signal breakdown it becomes clear that this is some kind of off by 1 error. The input sample is 0b111010010101 which is not equal to the binary sample in the above image.

Saturday, September 27, 2014

So... What do you do in your free time?

This is a pretty awkward question that I never know how to answer. Especially at work. Recently my time has been going into a personal/hobby/electronics project.

I am doing a hardware implementation of Auto tune. This is not a novel concept and it would be much better implemented in a DSP. The purpose of the project is to sharpen a select set of skills. In order of priority:

  1. UVM testbench development 
  2. Hardware design
  3. Signal processing 
  4. FPGA validation -- I have a DE0 nano development kit for this
I took inspiration from an undergrad project where we implemented pitch correction in MATLAB. The algorithm uses a phase vocoder. I am still wrapping my head around many of the low level details. In general the algorithm processes overlapping time windows of the audio signal. The time windows are converted to the frequency domain for manipulation then converted back to the time domain to listen to.

I've started a functional decomposition for the RTL and I gave a general idea about how the blocks will communicate with each other. 

The flowchart should give a general idea of what I am trying to accomplish

High level block diagram for how I will separate the logic

I've also been making many mistakes and learning a lot as I go.
  1. Drive an interface you didn't instantiate? Code compiles fine, simulator crashes :) fun
  2. Driver bugs: not checking chip select before sending a transaction to the DUT
  3. Zero time loops. Oops!
  4. RTL issues. My implementation for the most basic block already has a flaw. Samples needs to be pulled from the ADC at 200 ksps. Unfortunately my current design has no parallelism so it doesn't meet the timing requirements. Not sure if adjusting clock frequencies will help or if a RTL redesign is needed.
  5. The sample driven into the DUT (adc) is not the same as the sample passed to the next block (trying to debug)