how to do a left shift in Modelsim in order to built a booth multiplier - modelsim

I am writing a code for Booth Multiplier in ModelSim. Currently, I am implementing my code in a for loop. In the for loop there are if..else conditions that are checking 2 bits at a time of the multiplier. Here I need to do a left shift of the multiplicand but I am unable to do so.
How can we do a left shift in ModelSim since the shift operators don't work here?

In VHDL a two bit shift looks like this:
shifted := unshifted(unshifted'high-2 downto 0) & "00";

Related

How to know if vector is undefined

What I have
I've a signal of std_logic_vector. I need to give it values from a ROM, what I already do.
The problem
At the beginning of the simulation or use, there's an initialization process which makes it to need some time before ROM returns it first value (about 2 clk period).
Until then, ROM output vector is "UUUU" (since it's 4 bits of width). Let's call this signal ROM_coef_inf, so in simulation, this appears with "UUUU" value, so its colour is orange.
I need
I need to know how can I compare this output in order to know if it's an "undefined vector", in order to give another value (i.e. "0000") to my vector until the first ROM value is ready.
There are several possible solutions:
You could initialize all registers between your ROM and your destination (at least in simulation) with a different value to "UUUU".
A standard compare can test for all 9 STD_LOGIC values:
if (mySignal == 'U') then
You can test signals for special values with is_x(...).
Is is defined like this:
FUNCTION Is_X ( s : std_ulogic) RETURN BOOLEAN IS
BEGIN
CASE s IS
WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
WHEN OTHERS => NULL;
END CASE;
RETURN FALSE;
END;
There are overload for vectors, too.
I assume this is for FPGA use, in which case all registers will have a predictable value after programming, which is zeros unless you specify something else. If all you need is for ROM_coef_inf to have zeros instead of U's for the first clock cycles in simulation, you can simply specify an initial value when declaring the signal:
signal ROM_coef_inf : std_logic_vector(3 downto 0) := "0000";
In ASICs registers will have an unknown value after power is applied. In this case you need to use a reset signal to clear all the registers in your design. It is often a good idea to use a reset signal in an FPGA as well, for example to prevent your circuit from doing anything until the clock is stable.
The answer provided by #Paebbels works only in simulation. In the real world the signals tend to be either an 1 or a 0 (or a transition between them, but that is not discussed here). Number 1 will work, but you need to set it to a value that will never occur in your ROM if you want to check for uninitialized. The simpler option is to count clock cycles. The ROM will always behave the same. So if it takes three cycles to get the first data out, it will always take three cycles. So if you count three cycles you are ok.

ATMega peformance for different operations

Has anyone experiences replacing floating point operations on ATMega (2560) based systems? There are a couple of very common situations which happen every day.
For example:
Are comparisons faster than divisions/multiplications?
Are float to int type cast with followed multiplication/division faster than pure floating point operations without type cast?
I hope I don't have to make a benchmark just for me.
Example one:
int iPartialRes = (int)fArg1 * (int)fArg2;
iPartialRes *= iFoo;
faster as?:
float fPartialRes = fArg1 * fArg2;
fPartialRes *= iFoo;
And example two:
iSign = fVal < 0 ? -1 : 1;
faster as?:
iSign = fVal / fabs(fVal);
the questions could be solved just by thinking a moment about it.
AVRs does not have a FPU so all floating point related stuff is done in software --> fp multiplication involves much more than a simple int multiplication
since AVRs also does not have a integer division unit a simple branch is also much faster than a software division. if dividing floating points this is the worst worst case :)
but please note, that your first 2 examples produce very different results.
This is an old answer but I will submit this elaborated answer for the curious.
Just typecasting a float will truncate it ie; 3.7 will become 3, there is no rounding.
Fastest math on a 2560 will be (+,-,*) with divide being the slowest due to no hardware divide. Typecasting to an unsigned long int after multiplying all operands by a pseudo decimal point that suits your fractal number(1) range that your floats are expected to see and tracking the sign as a bool will give the best range/accuracy compromise.
If your loop needs to be as fast as possible, avoid even integer division, instead multiplying by a pseudo fraction instead and then doing your typecast back into a float with myFloat(defined elsewhere) = float(myPseudoFloat) / myPseudoDecimalConstant;
Not sure if you came across the Show info page in the playground. It's basically a sketch that runs a benchmark on your (insert Arduino model here) Shows the actual compute times for various things and systems. The Mega 2560 will be very close to an At Mega 328 as far as FLOPs goes, up to 12.5K/s (80uS per divide float). Typecasting would likely handicap the CPU more as it introduces more overhead and might even give erroneous results due to rounding errors and lack of precision.
(1)ie: 543.509,291 * 100000 = 543,509,291 will move the decimal 6 places to the maximum precision of a float on an 8-bit AVR. If you first multiply all values by the same constant like 1000, or 100000, etc, then the decimal point is preserved and then you cast it back to a float number by dividing by your decimal constant when you are ready to print or store it.
float f = 3.1428;
int x;
x = f * 10000;
x now contains 31428

rounding to the nearest zero, bitwise

I just wonder how can i round to the nearest zero bitwise? Previously, I perform the long division using a loop. However, since the number always divided by a number power by 2. I decide to use bit shifting. So, I can get result like this:
12/4=3
13/4=3
14/4=3
15/4=3
16/4=4
can I do this by performing the long division like usual?
12>>2
13>>2
if I use this kind of bit shifting, are the behavior different for different compiler? how about rounding up? I am using visual c++ 2010 compiler and gcc. thx
Bitwise shifts are equivalent to round-to-negative-infinity divisions by powers of two, meaning that the answer is never bigger than the unrounded value (so e.g. (-3) >> 1 is equal to -2).
For non-negative integers, this is equivalent to round-to-zero.

Driving Dual 7 Segment Display Using Arduino

Okay, so I am trying to drive a 7 segment based display in order to display temperature in degrees celcius. So, I have two displays, plus one extra LED to indicate positive and negative numbers.
My problem lies in the software. I have to find some way of driving these displays, which means converting a given integer into the relevant voltages on the pins, which means that for each of the two displays I need to know the number of tens and number of 1s in the integer.
So far, what I have come up with will not be very nice for an arduino as it relies on division.
tens = numberToDisplay / 10;
ones = numberToDisplay % 10;
I have admittedly not tested this yet, but I think I can assume that for a microcontroller with limited division capabilities this is not an optimal solution.
I have wracked my brain and looked around for a solution using addition/subtraction/bitwise but I cannot think of one at all. This division is the only one I can see.
For this application it's fine. You don't need to get bothered with performance in a simple thermometer.
If however you do need something quicker than division and modulo, then bitwise operations come to help. Basically you would use bitwise & operator, to compare your value to display with patterns describing digits to be displayed on the display.
See the project here for example: http://fritzing.org/projects/2-digit-7-segment-0-99-counting-with-arduino/
You might also try using a 7-seg display driver chip to simplify your output and save pins. The MC14511BCP (a "4511") is a good one. It'll translate binary coded decimal (BCD) to the appropriate 7-seg configuration. Spec sheets are available here and they can be commonly found at electronics parts stores online.

Determine true north

I am working on an Arduino device I am building.
I have bought a GPS module and a tilt sensing compas with an accelerometer.
I wish to determine true north so that I can always point an object towards the sun.
Basically I want the device to always find true north wherever it is.
The GPS will give a position, the compass will find magnetic north. I guess the true north can be obtained during movement of the device and written to RAM then retrieved for use when the device is stationary.
But how?
Are you trying to get the most sun for your rotational solar panel? If so then you can get away with just rough position setting between East and West according to your clock (you can improve this with taking long/lat position into the account to calculate sun rise and sun set times). You will need a lot of astronomy calculations if you want to control both azimuth and elevation precisely. Arduino does not support double, and with single you will not have very accurate results (they will be enough for solar panel tracker, but not enough if you want telescope to track some sky object). My advice would be to either investigate a lot on the topic, or take a look at some open source astronomy software and extract the needed calculations from the source (if licence terms permit). Just to give you a hint, this is a small extract from PilotLogic TMoon component that you can get in CodeTyphon/Lazarus/FPC installation package found here:
procedure Sun_Position_Horizontal(date:TdateTime; longitude,latitude: extended; var elevation,azimuth: extended);
var
pos1: T_Coord;
begin
pos1 := sun_coordinate(date);
calc_horizontal(pos1,date,longitude,latitude);
end;
function sun_coordinate(date:TDateTime):t_coord;
var
l,b,r: extended;
lambda,t: extended;
begin
earth_coord(date,l,b,r);
(* convert earth coordinate to sun coordinate *)
l := l+180;
b := -b;
(* conversion to FK5 *)
t := (julian_date(date)-2451545.0)/365250.0*10;
lambda:=l+(-1.397-0.00031*t)*t;
l := l-0.09033/3600;
b := b+0.03916/3600*(cos_d(lambda)-sin_d(lambda));
(* aberration *)
l := l-20.4898/3600/r;
(* correction of nutation - is done inside calc_geocentric *)
{ calc_epsilon_phi(date,delta_phi,epsilon); }
{ l := l+delta_phi; }
(* fill result and convert to geocentric *)
result.longitude := put_in_360(l);
result.latitude := b;
result.radius := r*AU;
calc_geocentric(result,date);
end;
procedure calc_horizontal(var coord:t_coord; date:TDateTime; longitude,latitude: extended);
var
h: extended;
begin
h := put_in_360(star_time(date)-coord.rektaszension-longitude);
coord.azimuth := arctan2_d(sin_d(h), cos_d(h)*sin_d(latitude)-
tan_d(coord.declination)*cos_d(latitude));
coord.elevation := arcsin_d(sin_d(latitude)*sin_d(coord.declination)+
cos_d(latitude)*cos_d(coord.declination)*cos_d(h));
end;
If you had a case that your device is not moving after installation (which is not the case after I reread your question so you can ignore the rest of the message), then your longitude and latitude are fixed and you know them at compile time, or you can enter them manually when device is first installed. That way GPS is not needed. You can also find North once at installation time, so you don't need compass either.
Compass will get haywire when it gets near some magnetic material and will not be practical at all. You can calculate the azimuth and elevation of the sun with respect to your location. It is more practical to use some digital encoders with your system and make calculated incremental movements. A calibrate button on the arduino could be used to normalize the parameters using a standard tools. For fine tune, manual buttons could be provided for up and down movements.

Resources