Wednesday, March 16, 2011

SystemVerilog struct assignment

You may have occasion to initialize a structure in SystemVerilog:

typedef struct {
int f1;
int f2;
int f3;
} set_of_values_T;

set_of_values_T set_of_values = {1, 2, -3};


This might seem fine, but the above assignment is actually a concatenation. The simulator will take the set of values and pack them into one big bit vector.

In my experience, Modelsim was okay with positive values, or a mix of positive and negative values. In compilation, it would note that it was promoting an assignment to a concatenation. But if all the values were negative, it would give an error that a packed value was being assigned to an unpacked value.

A quick Google search turned up a book preview that showed an example of how to initialize a structure. Very simple, really. Just add a tick (') before the assignment:


set_of_values_T set_of_values = '{1, 2, 3};


This does the trick, and the notes and errors go away. SystemVerilog uses the '{} construct to differentiate a list of values from a concatenation, {}.

EDIT: Another example, this time with a dynamic array or queue:


bit [0:2] values[$]= '{3,5,6};

Tuesday, February 22, 2011

Engineering Economics

I'm going to deviate from technical discussion and get into money a little. Engineers are often under pressure to reduce costs. Someone asked for advice this week on removing a couple of parts that are not needed for a particular version of a product that we are shipping. Removing those parts has some implications, which include testing to verify that there are no "gotchas", possibly releasing a new program image to account for the parts not being there, further testing of that new image, and so on.

It's good for engineers to have at least some grasp of the tradeoffs involved in their decisions. In this case, we are talking about 14 cents of savings per board. At 5,000 units per year, this comes out to $700. (Network infrastructure does not have the volumes of consumer products.) At 10,000 we are at $1400. Is it worth the time?

How much is engineering time worth? You could try to figure the hourly cost. Divide the salary by 2,000 hours per year. Don't forget to add the cost to the employer of benefits, employer's share of taxes, worker's comp, office space, supplies, all that expensive depreciating equipment in the lab. $100/hour is probably low. What about $500? Maybe.

What else could an R&D engineer be spending his time on? What about new product development?

How much does an engineer bring to the bottom line in new product development? How much of the profits should be allocated to engineering? We grudgingly have to give some credit to marketing, legal, human resources, and other groups that keep the company going. Say engineers make up a third of the overhead. Then maybe it's fair to take credit for a third of the net profit.

How much profit for a new product? We can look at net margins for the business and figure what percentage of overall business profits is due to the new product.

The higher the volumes, the more it makes sense to pay someone to work on the problem, whether it's taking 14 cents of parts off a board, or developing a new product. We engineers are often isolated from these kinds of numbers, especially in a large company. We rely on upper management to set our priorities. But we can at least throw around some rough numbers and figure out if we are pulling our weight.

Friday, February 11, 2011

Arbitrary voltage source in LTSpice

Here is a post I found when searching for a way to use some data as an input to LTSpice to test a filter.

http://ltspicelabs.blogspot.com/2006/10/using-wav-files-for-io-and-transient.html

This talks about taking a .wav file as input. Which is fine if you are doing audio. But what if you want to generate a .wav file based on, say, a mathematical model?

Python has a nice wave module. So you could write a short script like this:

# Send data to output .wave file
# filename = string
# fsys = integer system clock rate
# data = list of integers
def writewave(filename, fsys, data):
oversample_factor = 8
offset_factor = 16384
scale_factor = 60 # 8 bit in to ~15 bit out

w = wave.open(filename, 'wb')
w.setnchannels(1)
w.setsampwidth(2)
w.setframerate(fsys * oversample_factor) # need to oversample to generate the steppy DAC output
w.setnframes(len(data))
d = '' # string to hold byte values in little-endian order
for i in data:
ii = scale_factor * i + offset_factor
rl = int(ii) & 255
rh = (int(ii) >> 8) & 255
for j in xrange(oversample_factor):
d = d + chr(rl) + chr(rh) # little-endian
w.writeframes(d)
w.close()

This will write out your data to a .wav file that can then be used in LTSpice. The example here has a sample width of 2, which would be two bytes, or signed 16 bits. I was modeling a signed 8-bit DAC output, so I scaled it up and offset it to get what I wanted. Also I put in an oversampling factor to get a more step-wise response instead of a linear ramp between sample points.

Don't forget "import wave" in the Python script!