6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 13, 2024 1:04 am

All times are UTC




Post new topic Reply to topic  [ 164 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next
Author Message
PostPosted: Fri Aug 19, 2016 2:46 pm 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
Tests have proven me wrong so I have to step back to the noise question again :(

According to the timing diagrams and the schematics the shift is performed in two steps and starts one cycle after bit 19 of the oscillator goes high. The following table shows the noise clock status during shifting:

Code:
     | bit19 | clk | LC c1 c2 |
-----|-------|-----|----------|
clk1 |   0   |  1  | 0  1  1  |
clk2 |   0   |  1  | 0  1  1  |
-----|-------|-----|----------|
clk1 |   1   |  1  | 0  1  1  | <- bit19 raises
clk2 |   1   |  1  | 0  1  1  |
-----|-------|-----|----------|
clk1 |   1   |  0  | 1  0  0  | <- shift phase 1
clk2 |   1   |  0  | 1  0  0  |
-----|-------|-----|----------|
clk1 |   1   |  1  | 0  1  0  | <- shift phase 2
clk2 |   1   |  1  | 0  1  1  |


In the first step bits are interconnected and the output of each bit is latched into the following.
In the first clock half of the second step the latched value becomes active.

Code:
    bit n     |   bit n+1
 latch output | latch output
--------------|--------------
   A <-> A    |   B <-> B
   A <-> A    |   B <-> B
--------------|--------------
   A <-> A    |   B <-> B
   A <-> A    |   B <-> B
--------------|--------------
   X     A  --|-> A     B      <- shift phase 1
   X     A  --|-> A     B
--------------|--------------
   X --> X    |   A --> A      <- shift phase 2
   X <-> X    |   A <-> A


If test or reset signals are active the phase 1 is repeated at each cyle until the signal is released triggering the second phase.

The interesting thing that emerged when running some test programs on a c64 is that the writeback only happen when combined waveforms are selected during both phases of the shift:

Code:
phase 1 |   noise   | noise+saw | noise+saw
phase 2 | noise+saw | noise+saw |   noise
--------|-----------|-----------|-----------
result  |    no     | writeback |    no
        | writeback |           | writeback


Furthermore the same combination that drives down the bits must be included in both steps, i.e having noise+triangle and then noise+sawtooth won't change the bits while switching from noise+saw to noise+saw+triangle will.
I would have expected that having combined waveforms pulling down the bits during the first step was enough to affect the LFSR register state but actually it is not. If anyone have a good explanation for this it would be nice to hear :)


Top
 Profile  
Reply with quote  
PostPosted: Thu Sep 01, 2016 9:31 am 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
Ok, it's time to move on to the remaining digital part of the sound synthetizer.

The envelope generator alters the waveform amplitude based on four 4-bit parameters (attack, decay, sustain and release) and the gate signal to mimic real instruments sound dynamic.
The envelope output is an 8 bit value, clocked up or down depending on the state, which modulates the waveform output through an MDAC.
When the gate goes high the volume raises up to $ff linearly then it falls down exponentially to the sustain level. Once the gate is released the volume goes down exponentially to zero.
A 15 bit LFSR is used to divide the clock during the attack phase providing 16 different attack rates, ranging from 2ms to 8s. Another 5 bit LFSR further divedes the clock during the decay/release phases to approximante an exponential curve, ranging from 6 ms to 24 s. The stop-points for the LFSRs are determined by two LUTs indexed by the ADR values.
More details in the technical documentation [1].

The envelope generator is also afflicted by some "bugs", like the counter wrapping when switching quickly between attack and release or the infamous ADSR-Bug [2], which may cause the attack of a note to start with quite a few cycles of delay after the gate is set.

[1] http://www.sidmusic.org/sid/sidtech2.html
[2] http://www.codebase64.org/doku.php?id=b ... _generally


Top
 Profile  
Reply with quote  
PostPosted: Thu Sep 01, 2016 11:38 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
Three things to say:

First: if the designers would have built the envelope generator according to the school books,
maybe it would have taken 50% more space on the silicon. ;)

Second: had no time to check what exactly happens in which clock cycle,
so please don't take the cycle counts in my block diagram too serious, sorry.

Third: the SID uses a LFSR (linear feedback shift register) as a noise generator.
While the binary sequence generated by a LFSR looks somewhat random to the human eye,
it certainly _is_ a predictable sequence, so the designers used two LFSRs as counters.

Block diagram of the envelope generator:
Attachment:
envelope_block.png
envelope_block.png [ 295.98 KiB | Viewed 8753 times ]


We now initiate the envelope generator by setting 'Gate' to 1 to start 'Attack phase'.

We have a 15 bit LFSR counter running at PHI2 speed, feeding a PLA with its outputs.
The PLA compares the LFSR with a value according to the registers: 'Attack', 'Decay' and 'Release'.
(Register is selected by the 'envelope control block.)
At the moment, it's 'Attack' register.
If the LFSR has reached a certain value, it is set to $7FF,
(since $000 would freeze the LFSR counter, all bits are set to start a new counting sequence)
and during 'Attack phase' the 8 bit envelope counter (which feeds the envelope DAC that sets
the amplitude of the analog waveform signal from the oscillator block) "increments" by one step.

So the 15 bit LFSR counter is in fact a predivider, that divides down PHI2.
Example: 'Attack phase', 'attack register' is $0, 2.048ms Attack time.
If PHI2 is 1MHz (1us clock cycle) and the LFSR15 counter divides it by 8,
the envelope DAC counter "increments" at 1MHz/8, that's 125khz (8us clock cycle).
Since the envelope DAC counter is 8 bit, "incrementing" it from $00 to $FF takes 256 clock cycles
8us each, that's 8us*256=2048us... or 2.048ms.

After the envelope DAC counter has reached $FF, 'Attack phase' ends and 'Decay phase' starts.
From here, the envelope DAC counter starts "decrementing" back toward $00.
The evil thing here is, that it doesn't count down in a linear fashion like when counting up.
Depending on the value in the envelope DAC counter, count frequency is changed to make the amplitude drop
nonlinear, in other words to make it look somewhat "exponential".
For this, we have another 5 bit LFSR counter feeding another little PLA.

When the envelope DAC counter has reached "Sustain level" while counting down,
'Decay phase' ends and 'Sustain phase' starts,
in which the counter does nothing.

When setting 'Gate' to 0, 'Sustain phase' ends and 'Release phase' starts.
The envelope DAC counter just continues with "decrementing" down to $00 in nonlinear fashion.

When the envelope DAC counter has reached $00, 'Release phase' ends
and the counter stops counting, waiting for 'Gate' to go 1 again.

;---

This was the simplified version, of course.

In the text above, I wrote "incrementing" or "decrementing" the envelope DAC counter.
Actually, the counter really is an up\down counter, but it usually counts up.
The counter has XOR gates at the outputs, and inverting the outputs of an up_counter
makes it _look_ like a down_counter.

We are getting there later, just don't get confused about this now...

;---

Edit:
After looking at the picture again in 2018, I think I have spotted some errors.

The XOR gate at the LFSR5 counter probably should connect to the Q2 output of the shift register instead of the /Q2 output,
and I'm not sure about the polarity of the release_reset signal.


Last edited by ttlworks on Wed Jan 10, 2018 9:33 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 02, 2016 10:14 am 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
Now that we have a good overview we can dive into the details. Let's start from the core, the envelope counter, built as an 8 bit ripple counter with inverted odd bits.

This is the layout of two adjacent bits:

Attachment:
counter_bit_IC.png
counter_bit_IC.png [ 50.62 KiB | Viewed 8722 times ]


The even bits are comprised of an XOR logic, that sums the Carry in and the previous bit value, and an inverted XOR gate that inverts the output when counting downwards. The bit value gets inverted when the cnt_clk_inv is high, which happens when counting direction switches.

Attachment:
counter_bit_even.png
counter_bit_even.png [ 26.42 KiB | Viewed 8722 times ]


The carry output is calculated as following:
Cout = ¬(/Cin ∨ /bit_old)

The new bit value is obtained with this formula:
bit_new = ¬(Cout ∨ (/bit_old ∧ /Cin)) = /Cin + /bit_old

And the bit output is calculated as:
cnt_out = ¬((bit_new ∧ ¬cnt_up) ∨ (¬bit_new ∧ cnt_up)) = ¬(bit_new + cnt_up)

(bit_old is used in place of /bit_old when cnt_clk_inv is active)

For the odd bits the first XOR logic is inverted.

Attachment:
counter_bit_odd.png
counter_bit_odd.png [ 25.32 KiB | Viewed 8722 times ]


The carry output is calculated as following:
/Cout = ¬(Cin ∧ bit_old)

And the new bit value is obtained with this formula:
/bit_new = ¬(/Cout ∧ (bit_old ∨ Cin)) = ¬(Cin + bit_old)

And the bit output is calculated as:
/cnt_out = ¬((/bit_new ∧ ¬cnt_up) ∨ (¬/bit_new ∧ cnt_up)) = ¬(/bit_new + cnt_up)

(/bit_old is used in place of bit_old when cnt_clk_inv is active)

These tables summarize the bit logic:

Code:
Even:
/Cin|/bit_old|Cout|bit_new
----|--------|----|-------
  0 |    0   | 1  |   0
  0 |    1   | 0  |   1
  1 |    0   | 0  |   1
  1 |    1   | 0  |   0

cnt_up|bit_new|cnt_out
------|-------|-------
  0   |   0   |   1
  0   |   1   |   0
------+-------+-------
  1   |   0   |   0
  1   |   1   |   1


Odd:
Cin|bit_old|/Cout|/bit_new
---|-------|-----|--------
 0 |   0   |  1  |    1
 0 |   1   |  1  |    0
 1 |   0   |  1  |    0
 1 |   1   |  0  |    1

cnt_up|/bit_new|/cnt_out
------|--------|--------
  0   |    0   |    1
  0   |    1   |    0
------+--------+--------
  1   |    0   |    0
  1   |    1   |    1


As expected the bit_new value is the sum of bit_old and the carry from the previous bit. The input carry for bit 0, active low, controls the counter clocking while the cnt_up signal controls the counter direction, inverting the output when low. The feedback loop is controlled by the cnt_clk signal except in the cycle when counting direction changes during which cnt_clk_inv is used to invert the bit values.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 02, 2016 10:38 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
Envelope DAC counter.

Even bits: low_active carry input, counter bit is stored active high, high_active carry output.

Odd bits: high_active carry input, counter bit is stored active low, low_active carry output.

Attachment:
env_dac_cnt.png
env_dac_cnt.png [ 75.27 KiB | Viewed 8719 times ]


Note, that the counter really is an up\down counter,
but it usually counts up.

When the envelope DAC counter is "incrementing",
the counter usually counts up while the XOR gates fed by Z,/Z don't invert the counter outputs.

When the envelope DAC counter is "decrementing",
the counter usually counts up while the XOR gates fed by Z,/Z do invert the counter outputs,
what makes the counter that counts up just look like a counter that counts down...

And I'm sure that this will cause quite some confusion to some of our readers. :)

;---

Looks like drfiemost has changed the notation of some of the signals.
IMHO the new signal names won't be too helpful for understanding the circuitry,
so I'm going to stick with the old notation I had in my envelope generator block diagram, sorry.

In my schematics above, X1 makes the counter count up, X2 makes the counter count down.
(X1 or X2 are active when sid_clk2 =1.)

Z=0, /Z=1 does not invert the counter outputs //up_counter looks like up_counter.
Z=1, /Z=0 does invert the counter outputs //up_counter looks like down_counter.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 02, 2016 10:54 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
I suppose, that counter control and envelope control are next. :)
Attachment:
env_dac_cnt_ctl.png
env_dac_cnt_ctl.png [ 201.83 KiB | Viewed 8716 times ]


Edit:
Because of the density and complexity of the envelope generator,
we had dissected it indepentently of each other,
then compared our results for weeding out the errors.

Edit2 (December 2017):
More than a year later and after digging into that part of the silicon again, I think my schematic above contains errors.
For more info, see here.


Last edited by ttlworks on Wed Dec 13, 2017 9:06 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 05, 2016 2:11 pm 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
ttlworks wrote:
Looks like drfiemost has changed the notation of some of the signals.
IMHO the new signal names won't be too helpful for understanding the circuitry,
so I'm going to stick with the old notation I had in my envelope generator block diagram, sorry.

Yes, I've renamed a few lines trying to make them more meaningful, at least to my understanding.
I apologize for any confusion this may cause, here is the mapping if it helps:

X1 => clk_cnt
X2 => clk_cnt_inv
/Z => cnt_up
Z => /cnt_up

This is the circuit that generates these signals:

Attachment:
R0_IC.png
R0_IC.png [ 66.65 KiB | Viewed 8683 times ]


R0 and cnt_up reflects the counting_direction signal state with respectively one and two cycles delay.
The cnt_clk and cnt_clk_inv signals are derived through an XOR gate, that checks when counting_direction has changed from the previous clock cycle, and two NOR ports, that make one of the signals active during the sid_clk2 phase based on the XOR output. The result is that cnt_clk_inv is high only the cycle after counting_direction has changed.

Attachment:
R0.png
R0.png [ 43.24 KiB | Viewed 8683 times ]


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 07, 2016 2:17 pm 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
This is the logic that controls the counting direction:

Attachment:
Counting_direction_IC.png
Counting_direction_IC.png [ 75.62 KiB | Viewed 8658 times ]


Basically two cross-connected NOR gates forming an SR flip-flop which reacts on changes of the gate and the 0xFF signals. The latter, we will see, triggers once the counter value becomes $ff.

Attachment:
Counting_direction.png
Counting_direction.png [ 32.97 KiB | Viewed 8658 times ]


So the counting direction will be set when the gate bit goes high and reset when gate goes low or when the counter reaches its maximum value.


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 07, 2016 4:05 pm 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
Thanks for clarifying the signal names for the new notation. :)

IMHO it would be better to sort out what happens where in that circuitry
in which clock cycle later, and to go on with dissecting the rest of the chip.

;---

Now about the "sustain comparator", which compares the output of the 8 bit envelope DAC counter
to the output of the 4 bit sustain register.

It's an 8 bit comparator, comparing env7..4 with sust3..0, and env3..0 with sust3..0.

If the counter output matches the "sustain level" in 'Decay phase' while counting down,
a comparator match starts 'Sustain phase' in which the counter does not count.

One bit of the comparator:
Attachment:
env_sustain_cmp.png
env_sustain_cmp.png [ 20.06 KiB | Viewed 8652 times ]


8 of the circuits above have their outputs wired together to a line I had named 'XOR_cmp',
together with a pullup resistor to +5V.

If (at least) one of those 8 circuits has different levels on the env_x and sustain_y inputs,
'XOR_cmp' is pulled to GND to indicate that the envelope DAC counter output does not match "sustain level".

;---

Of course, this was the simplified version.

On transistor level, 'XOR_cmp' =1 stops the counter, no matter what.
So in addition to the sustain comparator outputs, 'XOR_cmp' also is tied to GND by FETs
if R0 =1 ('Attack phase'), or if /R1 =1 (Gate =0, 'Release phase').


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 6:10 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
Control registers for Attack, Decay, Sustain, Release.
Attachment:
env_ctl_reg.png
env_ctl_reg.png [ 15.02 KiB | Viewed 8624 times ]


Nothing fancy in there, non_inverted outputs,
all registers except Sustain have output enable.

BTW:
The write enable signals are clobbered down by FETs if PHI2 =0.
IMHO this is because the PolySi traces for the write enable signals
are quite long and have some resistance...
forming up a "low_pass" with the capacitances in the registers.
So the designers had added those FETs as a "kludge"
to meet the bus hold timing requirements.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 6:37 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
The inverted and non_inverted outputs of the envelope DAC counter
are feeding 7 AND gates, which check for:
$00, $06, $0E, $1A, $36, $5D, $FF.

The outputs of two of those AND gates goes to the envelope\counter
control circuitry, detecting if the counter is $00 or $ff.

But those 7 AND gates also feed five RS flipflops through transparent
latches (transparent during sid_clk1 =1.)

Circuitry for one of those five RS flipflops:
Attachment:
env_detect.png
env_detect.png [ 17.32 KiB | Viewed 8624 times ]


During 'Decay phase' and 'Release phase', the outputs of those five RS flipflops
which are feeding the small PLA above the LSR5 counter cause a non_linear decrease
of the envelope DAC counter value by slowing down the DAC counter...
according to the value the DAC counter has at the outputs.

In my big block diagram, I had simplified things by drawing just one transparent register
between the RS flipflop outputs and the small PLA instead of 15 tiny registers, sorry. :)

The FPF output of those five RS flipflops is wired together with a pullup to +5V,
so if all five RS flipflops are cleared, FPF isn't tied to GND and thus '1',
what makes the envelope DAC counter run at a normal (not slowed down) speed
during 'Decay phase' and 'Release phase'.

BTW: not more than one of those five RS flipflops is supposed to be set.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 6:40 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
Now about the LFSR15 counter.

Nothing fancy in there, it's just a 15 bit shift register
running at PHI2 speed.

BTW: Internally, the register stores the bits in inverted form.


Attachments:
env_lfsr15.png
env_lfsr15.png [ 17.16 KiB | Viewed 8624 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 6:54 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1393
The LFSR5 counter is based on the circuitry we know from the LFST15 counter,
it just looks a little bit more complicated:
Attachment:
env_lfsr5.png
env_lfsr5.png [ 16.12 KiB | Viewed 8621 times ]


Either LFSR5_clkS (shift) or LFSR5_clkH (don't shift, hold value)
is active during sid_clk2 =1.

Having that feedback path controlled by LFSR5_clkH was necessary
because else the LFSR5 counter would lose the stored bits
after 10..15ms or so without LFSR5_clkS being '1'.

;---

Circuitry for generating the two clock signals LFSR5_clkS and LFSR5_clkH
depending on if there was an "overflow" in the LFSR15 counter:
Attachment:
env_lfsr5_clk.png
env_lfsr5_clk.png [ 20.8 KiB | Viewed 8621 times ]


;---

Oh, and I nearly forgot:

For channel 3, there is a transparent register (transparent if sid_clk1 =1)
for reading the value of the envelope DAC counter.

The layout of the register bits is to 100% identical to the register
for reading the output of the OSC3 waveform DAC,
so I felt no need for drawing schematics for the register. :)

And with this, I'm now through with dissecting the envelope generator. Woot.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 1:33 pm 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
Great work! I'll keep on posting my annotated layers and transistor schematics for reference.

Here is the input carry for bit 0 (the rest of the circuit is included in previous picture):

Attachment:
Carry_zero_IC.png
Carry_zero_IC.png [ 13.94 KiB | Viewed 8603 times ]


Again two cross-connected NOR gates forming an SR flip-flop which enables the counter when gate raises or on chip reset and disables it when the 0x00 signals triggers.
Another NOR gate controls the clocking of the counter when it's active based on the release_reset and count=sustain signals.

Attachment:
Carry_zero.png
Carry_zero.png [ 55.69 KiB | Viewed 8603 times ]


The counter_enabled label is a bit misleading but I've left it untouched from the original layouts, sorry for the laziness.

One interesting "feature" of this logic is that when the counter is locked at $00, by switching on the gate and then turning it off before the counter is clocked again the envelope will count down wrapping to $ff until it gets back to $00.
A similar trick, in the opposite direction, can be achieved when counter is at $ff.


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 09, 2016 3:28 pm 
Offline
User avatar

Joined: Tue Jun 07, 2016 4:34 pm
Posts: 53
This is the sustain comparator, located under each counter bit (count=sustain => XOR_cmp):

Attachment:
sustain_comparator_IC.png
sustain_comparator_IC.png [ 12.12 KiB | Viewed 8598 times ]


The counter and sustain bits are simply XORed:

Attachment:
sustain_comparator.png
sustain_comparator.png [ 16.06 KiB | Viewed 8598 times ]


The sustain register is only 4 bit and is compared with both counter nibbles giving sixteen sustain levels: $00, $11 ... $ff.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 164 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: