|
|||||||
![]() |
|
|
Thread Tools |
|
|
#1 |
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
MACW wraparound
Greetings guys,
I wonder what is the PRACTICAL (I emphasize on that) use of the wraparound on overflow of the MACW and MACINTW instructions? Thanks in advance. |
|
|
|
|
|
#2 |
|
h/h member-shmember
Join Date: Dec 2002
Location: Evil Empire
Posts: 2,639
Rep Power: 69 ![]() ![]() ![]() ![]() ![]() ![]() |
There're many...
here's for example demo vibrato/chorus code (i gave it once before, but that thread was lost): Code:
name "delay line modulated by trangle lfo :)"
guid "d8dc1380-56ec-4098-960f-44e461f818d0"
control freq = 0.2 ; speed/frequency
control phase = 1 ; phase/panning/width
static s
temp b
input in1, in2
output out1, out2
control depth = 0.1
static osc1, osc2
static t1, t2
; delay lines
idelay write d1 at 0
idelay read d11 at 1000
idelay read d12 at 1000 ; we need two delay taps per channel to get it 'smoother'
idelay write d2 at 1001
idelay read d21 at 2001
idelay read d22 at 2001
itramsize 2002
const maxtime = 0x1f3000 ; maximum delay time -> (1000 - 4) * 0x800
; -4 used to prevent reading from 'alien' delay lines (when depth = 1)
; freq control workaround (as always)
macs b, 0, freq, 0.0008
macwn s, s, b, 1 ; saw osc
macw osc2, s, phase, 1 ; get shifted osc2
tstneg osc1, s, s, 0 ; osc1 saw->triangle
tstneg osc2, osc2, osc2, 0; ; osc2 saw->triangle
; feed delay lines
macs d1, 0, in1, 1
macs d2, 0, in2, 1
; calculate an interpolation coeffs for mixing taps...
; (or, in other words, 'fractional part of new address')
; (should be done one sample later, after writing t1/t2 to address regs)
macintw t1, 0, t1, 0x100000
macintw t2, 0, t2, 0x100000
; interpolate between taps and output (e.g. 'smoothing')
interp out1, d11, t1, d12;
interp out2, d21, t2, d22;
; applying depth
macs t2, 0, maxtime, depth
; modulation, calculates actual taps addresses (relative to base address of delays) and writes them
macs t1, &d1, t2, osc1 ; delay base address + new 'modulated' time
macints &d11, t1, 0x800, 2 ; first tap, time + 1 sample (should never be 0)
macints &d12, t1, 0x800, 3 ; second tap, time + 2 samples
macs t2, &d2, t2, osc2
macints &d21, t2, 0x800, 2
macints &d22, t2, 0x800, 3
end;
Last edited by Max M.; Apr 16, 2004 at 11:50 PM. |
|
|
|
|
|
#3 |
|
DH Senior Member
Join Date: Jan 2003
Location: The Netherlands
Posts: 1,932
Rep Power: 64 ![]() ![]() ![]() ![]() |
>>i gave it once before, but that thread was lost):
Yeah,..I still wonder who did that ![]() ../LeMury |
|
|
|
|
|
|
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Thanks very much. I've got another question if I may.
What is the purpose of the accumulator accesed via the MACMV instruction. I gues that it is a register that stores the result of the X*Y multiplication and according to the As10k manual it can be fetched with MACS, MACINTS or ACC3. Why is such a thing needed? Would you tell me in your next reply Max if I'm bothering you with this type of questions. |
|
|
|
|
|
#5 |
|
h/h member-shmember
Join Date: Dec 2002
Location: Evil Empire
Posts: 2,639
Rep Power: 69 ![]() ![]() ![]() ![]() ![]() ![]() |
It's a register in the heart of execution unit and it "stores full-width result of the last instruction's execution".
Accumulator is typically used "when extra headroom (the accumulator guard bits) or precision (the LS 32 of the accumulator's 67 bits) need to be retained through the next multiply/accumulate instruction". Or, in other words, you use it when you need "non saturated", "non wrapped" and "non truncated" result of previous operation (instruction)... Accumulator may be used only as A operand in any MAC** (except MACINT*) and ACC3. -------- Example - two "mixers": Code:
input in1, in2, in3, in4 control lev1, lev2, lev3, lev4 output y temp t macs t, 0, in1, lev1 macs t, t, in2, lev2 macs t, t, in3, lev3 macs y, t, in4, lev4 end Code:
input in1, in2, in3, in4 control lev1, lev2, lev3, lev4 output y macs 0, 0, in1, lev1 macs 0, accum, in2, lev2 macs 0, accum, in3, lev3 macs y, accum, in4, lev4 end In general, accumulator availability is very significant feature... - "Must-Have". Last edited by Max M.; Apr 19, 2004 at 02:07 PM. |
|
|
|
|
|
|
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
Thanks for the answer!
|
|
|
|
|
|
#7 | |
|
HardwareHeaven Extreme Member
Join Date: Jan 2005
Posts: 5,563
Rep Power: 62 ![]() ![]() ![]() ![]() ![]() ![]() |
Quote:
Registers only wrap around or saturate when the absolute value of that register > 1. Non wrapped or non saturated values would result in a floating point number, so how would the accum register handle that? I understand the extra precision, but not the "non wrapped" and "non saturated" part. |
|
|
|
|
|
|
|
|
|
kX user
Join Date: Apr 2004
Posts: 851
Rep Power: 0 ![]() |
You brought up my first post in the forum again
![]() From the 'As10k1' manual: Quote:
__________________
Miss you, Steve... |
|
|
|
|
|
|
#9 |
|
HardwareHeaven Extreme Member
Join Date: Jan 2005
Posts: 5,563
Rep Power: 62 ![]() ![]() ![]() ![]() ![]() ![]() |
I have read that manual many times but did not make the connection before. So what is the maximum overflow (4 bits = 15)?
I had tried some examples and it wasn't working (the main reason for my question), but I must have been doing something wrong because I tried a couple more and it worked this time. Here are the examples I tried (for future reference), similar to Max's above, but with number's plugged in for easy verification of the results. First Example: ------------------------- static a = 0.9, b = 0.5, c = 0; macs, 0, 0, a, b; (0.9 * 0.5 = 0.45) macs, 0, accum, a, b; (0.45 + 0.45 = 0.9) macs, 0, accum, a, b; (0.9 + 0.45 = 1.35) macsn, c, accum, a, b; (1.35 - 0.45 = 0.9) ------------------------- Result of above is 0x73333330 = 1932735280 / (2^31+1) = 0.89999999 = 0.9 Second Example: ------------------------- static a = 0.9, b = 0 macs 0, 0, a, a; (0.9 * 0.9 = 0.81) macs 0, accum, a, a; (0.81 + 0.81 = 1.62) macs 0, accum, a, a; (1.62 + 0.81 = 2.43) macsn 0, accum, a, a; (2.43 - 0.81 = 1.62) macsn b, accum, a, a; (1.62 - 0.81 = 0.81) ------------------------- Result of above is 0x67AE1478 = 1739461752 / (2^31+1) = 0.80999999 = 0.81 So, even though some of the intermediary results were floating point numbers, the final result was correct. Good stuff! Thanks again, -Russ |
|
|
|
![]() |
| Thread Tools | |
|
|