Beiträge von merlintwa im Thema „MOS6526 CIA detailed test vectors and models“

    Hi thierer,

    Yes your observations and mine agree, I used your descriptions as an input to move ahead and do all the many pulse shape variations in my testbench. Then from those pretty strange results try to come up with the verilog above, and run that against the testbench.

    Now from the measurements I have, the "best case" you describe does work, but not reliably. The unreliability is because the last bit (LSB) of every byte is sampled from the *next* byte, with a transparent path through the IC. This may or may not cause issues by itself.

    But what is more problematic is if there is a mix of 2-phi2 and 3-phi2 cycle bits.

    In the graph below (same as earlier but cleaned up a bit) the IC is first stimulated with 3-phi2 cycles per bit 0x1D. Then the stream switches to 2-phi2-cycle sending 0xE7. If you look closely, you can see one bit has been lost between the move from 3 to 2 phi2-cycle. The last bit of the 2nd byte is already shifted out before the SR register is loaded from the 8-bit-shift register internally, the output goes to 0xCF (which is 0xE7 shifted by one bit and the LSB from the next byte).

    So in this case where there are occasional 2-phi2 cycle bit in a stream, you will lose bits occasionally. This shorter 2-phi2 could also be influenced by a little setup and/or hold time and a little clock jitter (causing an instantaneous phi2 period to be a fraction shorter than average), so might be anything shorter than 2.1 phi2-cycles in a stream. Losing bits will probably lead to the internal bit shift counters of both systems getting out of sync. And that will cause a hang.

    The graph shows SP pin 0001 1101 1110 0111.

    Thank you for the very clear pictures!

    I have been progressing this week trying to further integrate your findings looking for the issue in my tests.

    I have added all possible CNT pulse lengths and phase offsets I could think of, plus some more-or-less random stimulus to see what the logic of CNT is.


    After that work I found I can now reproduce anything the CIA reports back on the Timer A output when in CNT count mode, using this input circuit: CNT is an input to a normal D-type Flip-Flop with an Asynchronous reset input. This feeds another flipflop that synchronizes the detected posedge to the PHi2 clock domain, and its output also resets the edge detector. So during the actual internal count pulse (when cnt_rr=1), you can do whatever you want on the CNT input - it is ignored.

    The funny thing is, the duty cycle issue you mention doesn't seem to come up in my tests for timer A. The rising edge is detected regardless if it is just a very short 1->0->1 pulse (like in your graph) or if it is a very short 0->1->0 pulse, or of it already goes 1->0 in the cycle before the posedge. Maybe it is a Serial Register exclusive issue, to do with that trasparent path I found. I will research that.

    The actual implementation of the CNT input stage might not be this exact circuit but this is the closest I can come up with explaining everything I've tested. Timer A then decreases itself using cnt_rr (which takes one cycle). Then if you read the TAL register the cycle after that, it is decreased.

    always @(negedge phi2 or resn) begin

    if(~resn) cnt_rr<= Bitte melde dich an, um diesen Link zu sehen. 0;

    else cnt_rr<=Bitte melde dich an, um diesen Link zu sehen. cnt_r;

    end

    always @(posedge cnt or posedge cnt_rr) begin

    if(cnt_rr) cnt_r<=Bitte melde dich an, um diesen Link zu sehen. 0;

    else cnt_r<= Bitte melde dich an, um diesen Link zu sehen. 1;

    end

    I am assuming the CNT input stage is also used for clocking in SDR.

    I will check if the FLAGN input has the same sort of behavior as this.

    Ok, thanks, I had not properly understood al the different software and stuff used. I've just looked up what's inside the xum1541 to figure out what you meant.

    So, I conclude from your FPGA experiments, you've seen max transfer rates close to 2 phi2 clocks per bit using a 6526R4 in a C64 as input, when you first phase-align the external FPGA with the chip. You then also make CNT only high for half of a PHI2 cycle, followed by 1.5 cycles low. Is that correct?

    That should also be possible then in my tests to observe. I'll try that scenario.

    So far I have not seen anything to suggest the length of the CNT high phase and low phase would make a difference, perhaps that is missing in the tests. I'm struggling to come to an IC design structure reason why that would make a difference.

    But what can easily happen when you have clocks running freely and there is a transparent path inside the IC, is that the internal timing is violated towards some parts of the logic like the IRQ capture but is just fast enough to have been seen as a data ready input.

    I'm sure you are fully aware of all metastability protection in modern ICs - the 6526 doesnt seem to have any protection in this case. Even in the 80s you would for sure design in a 1/2 cycle delay on all unsynchronised edges ariving on the IC. Like all the Port A and Port B input have. If you let such uncaptured edges then propagate out of your IC into the rest of your (synchronous) system you are asking for lots of random lockups and crazyness. Applying unsynchronised inputs to pins of chips, for pins that are designed for synchronous inputs only (like the 6510), can easly cause interal illegal states - completely unrelated to the pin connected even.

    When the source and destination clocks drift to just the right phase difference. I'd expect as long as the external sending system has a clock division that is guaranteed under all cases including clock jitter to be 2.5 cycles *or more* then it should work just fine. And in that case, some type of IRQ bug becomes a possible scenario again.

    Hi Skoe,

    Thanks for the heads-up, I've done a lot of designs in CMOS, also with pass gates, but I have never worked with the older NMOS. The oldest technology I worked on was 100nm.

    The diagram I sent above is an approximation of the reality using the actual Arduino vectors I used, I didn't even bother to set a `timescale directive so times are way off. I'll try posting a more accurate reflection of reality, with position of sample moments more accurate, later (still just an interpretation to make diagrams with).

    The actual speed of the Arduino is determined by the USB-serial delay it takes to send the measurement results as printf'ed strings to the PC. I did set the USB baudrate to max (1Mbit) for my setup.

    The full test I'm running right now (gets longer every day) is around 2000 phi2 cycles. It takes about 30 seconds of the Arduino to make one full testrun while also sending the results back to the PC. I setup the arduino to repeat the test after a 10s delay.

    I have not seen any issue running this slow - of course timing is very relaxed and the 6526 is not driving any high loads.

    With Arduino its not really an option to store measurement results in a buffer before sending them to the PC at the end - there isn't enough ram.

    If I understand that correctly, the Verilog isn't supposed to model the workings of a real CIA but the equivalent of what you're doing with your Arduino code, right? Otherwise I don't understand it because the original chip takes 4 PHI2 cycles per bit when sending, while the waveform you posted seems to have only two cycles per bit.

    > I think that's true for all the NMOS chips. (In contrast to the WDC versions, where I think you can halt and resume the clock at will).

    Ok, I had not realised that...

    Language is hard... Sorry about the confusion about clocks and phases and whatnot.

    The diagram shows an input test, CNT and SP are driven externally from the Arduino. CNT is changing 0->1 and 1->0 every PHI2 cycle as shown in the diagram.

    What I meant with IC "sends out" is that the chip sends CF over its 8-bit data bus to the arduino, so CF is really the value inside the SDR register of the chip. At this CNT rate, you can see the IC still works somewhat for input but is taking the output too late.

    If I am correct, what you are actually seing in that cycle is that the input bit present right on the same cycle the CF is read from the IC, is actually on the external pin at that same instant.

    That must means, during the cycle CF is read, there is a transparent path for 1/2 of the clock cycle through the entire IC direct to the processor's databus for the LSB bit all the way from the SP input.

    This has to be a design mistake or unintended consequence as you really need a minimum of 1/2 phase of PHI2 delay before taking a value from SP to allow for settling of the value after the latch closes. Then another latch while reading to ensure the internal state is streched beyond the end of the PHI2=1 phase.

    From this test it would not surprise me if this particular issue is just a symtom of a more problematic issue where the internal state's minimal internal timing delay is not met for this case when running at 1MHz. So you could get occasionally random incorrect internal state being latched in on a next cycle. Which could cause all sorts of issue. Hard to say. But whether this has any relationship to what you're seing would need a few different samples tested as such types of timing sensitive issues vary significantly between IC batches.

    I have'nt seen if you're looking at sending or receiving bits from the 1571, or both? Do the issues also occur at say lower speeds?

    Note on the diagram: the waveform is not an exact reflection of reality - The D pins of the CIA are sampled just before the negedge of phi2, and after that the D bus is tristate duting phi2=0. It also looks like the A pins arrive after the D change, and that D changes before phi2 even goes high - again this is just a converted version of the actual Arduino tests I'm doing. The places to look what the output of the IC are is on the negedges of phi2. The inputs do change like the graph shows - for this set of the tests at least - while phi2=0.

    So here with "clocks" you mean clock changes (not clock cycles), right?

    I mean phi2 clocks (not CNT clocks). Please not I'm running PHi2 from a GPIO of the Arduino, so effectively all my tests are (far slower than) 10kHz. But that is perfectly ok, I have not noticed any issues running 6526 very slow. Leaving the 6526 at DC 0Hz for a very long time like a few seconds or more, I have seen some weird stuff happen though. Like it resetting itself. Not sure if that is an artifact.

    In the test above there is a sequence somewhere halfway showing what I mean: (I hope pasting this works): This is the same information as above, but just run through verilog to create a waveform. At the bottom are 2 registers from my own verilog model, where you can observe the shifter shifting and that the IC sends out CF as value of SDR, which is one cycle too late. The proper value SDR should have been was 67.

    About the rest yes your analysis makes perfect sense. Indeed, like you mention, the output with phase uncertainty wont work between 2 6526's. So thats an IC design oversight I suppose, not taking into account the clock phase issues and capturing edge.

    Bitte melde dich an, um diesen Anhang zu sehen.

    Note that the IEC bus is behind 7406 open collector inverters. So knowing that the IEC bus is open collector doesn't meant that the CIA is open collector ;)

    Hi skoe,

    I would expect the NMOS versions of the 6526 to be very simillar to open-drain with a fairly low valued pull-up resistor (The PMOS) . But I have no experience with the HCMOS version, do you have any reason to believe an open-drain with pullup would not work in practice? Even at 3.3V? (given that the PLA doesn't even go above 3.6V I dont think there will be any issue running at 3.3V with 5V tolerance and maybe a small pulllup)

    Well, understanding what the tests are doing is exactly the ongoing trick of course :smile: Its just a list of actions sent to the IC, and observations of the internal state change. Interpretations are always difficult.

    Yes, there may be a bug like the Timer B bug - I would then also only expect those bugs in the so-called "old" 6526R4. But who knows. So far I have not seen this bug in my tests - but if it exists I will be able to find it. But if it is a bug similar to the timer B bug, it would present itself at any speed of operation of the serial port.

    I would currently find it more likely you're facing an improperly reset internal shift counter in some cases.

    In my tests I observe at the end of every 8 bits of transfer, at PHI/2 speeds, one bit is skipped in some as-yet unknown reason.

    At phi2/2 speeds, SP is really still sampled after 3 clocks, so in the same cycle the next CNT edge is created you can set the SP value for the *previous* bit.

    What seems to happen at phi2/2 speed in my tests is that when the shift register is full and needs to move its content to SDR, this overlaps with the same cycle as the next input bit arriving. So the data copied into SDR is actually one bit too late. Subsequently the reset of the shift counter seems to be off.

    This end of a byte internally seems to go wrong at phi/2. At least that is my best current guess from measurements I have.

    I'm fairly sure the IC was not intended to go this fast - the datasheet mentions SP is captured on posedge. That is true only if CNT is lower than PHI2/4. And that aligns with the max speed another 6526 on the same clock frequency is able to produce.

    For completeness here is my current test stream for the SDR input at higher speeds: Note that I observe that switching the SPMODE in CRA to output resets the INPUT shift regsiter. So I use SPMODE out for a few cycles to get into a known state of the internal input shift register.

    It is important to note I connect RS[2] (with resistor) to CNT, and RS[3] (with resistor) to the SP input. So reading or writing anything will set CNT, SP to the highest 2 bits of the 4-bit register address

    Same functions as above.

    P("Test SDR input from SP on CNT");

    W('hE,'h40); P("Write CRA: 40");

    W('hD,'h7F); P("Write ICR: 7F");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    W('hE,'h00); P("Write CRA: 00");

    R('hD,'h18); P("Read ICR");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('h8,'h09); P("Read TDT");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('hC,'h00); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h00); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h00); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hD,'h18); P("Read ICR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h09); P("Read TDT");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h09); P("Read TDT");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h00); P("Read TDT");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h00); P("Read TDT");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h2E); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h00); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h01); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h01); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h8,'h01); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('hC,'h55); P("Read SDR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h8,'h02); P("Read TDT");

    R('h8,'h02); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h8,'h02); P("Read TDT");

    R('h8,'h02); P("Read TDT");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h8,'h02); P("Read TDT");

    R('h8,'h02); P("Read TDT");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h55); P("Read SDR");

    R('hC,'h55); P("Read SDR");

    R('h8,'h02); P("Read TDT");

    R('h8,'h02); P("Read TDT");

    R('hD,'h18); P("Read ICR");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'h39); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'h39); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'h39); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'h39); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'h39); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'hCF); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'hCF); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'hCF); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'hCF); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('hC,'hCF); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'h36); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'h36); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('hC,'h36); P("Read SDR");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h94); P("Read SDR");

    R('hC,'h94); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h03); P("Read TDT");

    R('hC,'h94); P("Read SDR");

    R('hC,'h94); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h03); P("Read TDT");

    W('hC,'h89); P("Write SDR: 89");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h89); P("Read SDR");

    R('hC,'h89); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h03); P("Read TDT");

    R('hC,'h89); P("Read SDR");

    R('hC,'h89); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h03); P("Read TDT");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hD,'h18); P("Read ICR");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h36); P("Read SDR");

    R('hC,'h36); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h03); P("Read TDT");

    R('h4,'hFF); P("Read TAL");

    R('h4,'hFF); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hD,'h10); P("Read ICR");

    W('hE,'h41); P("Write CRA: 41");

    M(1,1,1,1,0,1); P("lines PCN: 1, IRQN: 1, PB7: 1, PB6: 1, SP: 0, CNT: 1");

    X('hFF,'hFF,'h00,'h00,'hFF,'hFF,'hFF,'hFF,'h03,'h00,'h00,'h12,'h36,'h08,'h41,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: FF TAH: FF TBL: FF TBH: FF TDT: 03 TDS: 00 TDM: 00 TDH: 12 SDR: 36 ICR: 08 CRA: 41 CRB: 00 ");

    M(1,1,1,1,0,1); P("lines PCN: 1, IRQN: 1, PB7: 1, PB6: 1, SP: 0, CNT: 1");

    X('hFF,'hFF,'h00,'h00,'hFF,'hFF,'hFF,'hFF,'h03,'h00,'h00,'h12,'h36,'h18,'h41,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: FF TAH: FF TBL: FF TBH: FF TDT: 03 TDS: 00 TDM: 00 TDH: 12 SDR: 36 ICR: 18 CRA: 41 CRB: 00 ");

    M(1,1,1,1,0,1); P("lines PCN: 1, IRQN: 1, PB7: 1, PB6: 1, SP: 0, CNT: 1");

    X('hFF,'hFF,'h00,'h00,'hFE,'hFF,'hFF,'hFF,'h03,'h00,'h00,'h12,'h36,'h18,'h41,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: FE TAH: FF TBL: FF TBH: FF TDT: 03 TDS: 00 TDM: 00 TDH: 12 SDR: 36 ICR: 18 CRA: 41 CRB: 00 ");

    M(1,1,1,1,0,1); P("lines PCN: 1, IRQN: 1, PB7: 1, PB6: 1, SP: 0, CNT: 1");

    X('hFF,'hFF,'h00,'h00,'hFD,'hFF,'hFF,'hFF,'h03,'h00,'h00,'h12,'h36,'h18,'h41,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: FD TAH: FF TBL: FF TBH: FF TDT: 03 TDS: 00 TDM: 00 TDH: 12 SDR: 36 ICR: 18 CRA: 41 CRB: 00 ");

    M(1,1,1,1,0,1); P("lines PCN: 1, IRQN: 1, PB7: 1, PB6: 1, SP: 0, CNT: 1");

    W('hE,'h01); P("Write CRA: 01");

    R('h4,'hFB); P("Read TAL");

    R('h4,'hFA); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('hC,'h65); P("Read SDR");

    R('hC,'h65); P("Read SDR");

    R('h8,'h03); P("Read TDT");

    R('h8,'h04); P("Read TDT");

    R('h4,'hF3); P("Read TAL");

    R('h4,'hF2); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    R('h4,'hEF); P("Read TAL");

    R('h4,'hEE); P("Read TAL");

    R('h0,'hFF); P("Read PA");

    R('h0,'hFF); P("Read PA");

    X('hFF,'hFF,'h00,'h00,'hEB,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h18,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: EB TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 18 CRA: 01 CRB: 00 ");

    X('hFF,'hFF,'h00,'h00,'hEA,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h18,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: EA TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 18 CRA: 01 CRB: 00 ");

    X('hFF,'hFF,'h00,'h00,'hE9,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h18,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: E9 TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 18 CRA: 01 CRB: 00 ");

    X('hFF,'hFF,'h00,'h00,'hE8,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h18,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: E8 TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 18 CRA: 01 CRB: 00 ");

    R('hD,'h18); P("Read ICR");

    X('hFF,'hFF,'h00,'h00,'hE6,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h00,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: E6 TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 00 CRA: 01 CRB: 00 ");

    X('hFF,'hFF,'h00,'h00,'hE5,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h10,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: E5 TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 10 CRA: 01 CRB: 00 ");

    X('hFF,'hFF,'h00,'h00,'hE4,'hFF,'hFF,'hFF,'h04,'h00,'h00,'h12,'h65,'h10,'h01,'h00,1);

    P("ic sc&rd: PA: FF PB: FF DDA: 00 DDB: 00 TAL: E4 TAH: FF TBL: FF TBH: FF TDT: 04 TDS: 00 TDM: 00 TDH: 12 SDR: 65 ICR: 10 CRA: 01 CRB: 00 ");

    Hi Thierer, Strik,

    So I got interested in the interrupt details from your questions, and I've tried to create a case like the Timer B bug. Which promptly appeared in my test output.

    Read 0xd: 0x93 // TA&TB irqs cleared.

    Scan 0xd: 0x82 // Scan means keep PHI2=1 and complete the cycle on a different address. CIA never completes the read-side-effects. TB underflows in this exact cycle.

    Scan 0xd: 0x91 // Timer A interrupt appears, Timer B present in last cycle has now disappeared. This is the infamous Timer B bug.

    I also tried testing what happens when CNT runs faster or slower and its effect on the IC. Below is a CNT test to the Timer A input.

    To understand whats below: it is important to note that I have connected RS[2] to the CNT input (with a series resistor)

    R() means a normal read cycle is done with phi2=1, the 2nd value is what the IC had on its output. Then , PHI2=0.

    L() Sets some lines to a value, D: FFFF means set to data input.

    P() are comments.

    The test does not always have the exact same result, below you can see one place where the delay of CNT to TA change is a cycle less than other cases. Actually that is the normal progression now I think of it.

    But I do get more and more the impression some part of the IC is running on phi2/2, from the FLAG and CNT capturing at higher speeds. Or the edge-capture logic is not being reset properly when FLAG or CNT run faster than phi2/3

    W('h4,'h03); P("Write TAL: 03");

    W('h5,'h00); P("Write TAH: 00");

    W('hD,'h83); P("Write ICR: 83");

    W('hE,'h31); P("Write CRA: 31");

    ...

    P("CNT 1->0->1->0->1 pulses, phi2= fixed 1");

    R('h4,'h01); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h4,'h00); P("Read TAL");

    L(1,0,1,'h0,'hFFFF); P("Set PHI2: 1, CSN: 0, RWN: 1, RS: 0, D: FFFF");

    L(1,0,1,'h4,'hFFFF); P("Set PHI2: 1, CSN: 0, RWN: 1, RS: 4, D: FFFF");

    L(1,0,1,'h0,'hFFFF); P("Set PHI2: 1, CSN: 0, RWN: 1, RS: 0, D: FFFF");

    L(1,0,1,'h4,'hFFFF); P("Set PHI2: 1, CSN: 0, RWN: 1, RS: 4, D: FFFF");

    R('h4,'h00); P("Read TAL");

    R('h4,'h00); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    P("CNT 1->0->1->0->1 pulses, phi2= fixed 0");

    L(0,0,1,'h0,'hFFFF); P("Set PHI2: 0, CSN: 0, RWN: 1, RS: 0, D: FFFF");

    L(0,0,1,'h4,'hFFFF); P("Set PHI2: 0, CSN: 0, RWN: 1, RS: 4, D: FFFF");

    L(0,0,1,'h0,'hFFFF); P("Set PHI2: 0, CSN: 0, RWN: 1, RS: 0, D: FFFF");

    L(0,0,1,'h4,'hFFFF); P("Set PHI2: 0, CSN: 0, RWN: 1, RS: 4, D: FFFF");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    P("CNT = PHI2 4 pulses A2");

    R('h4,'h02); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h4,'h02); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h4,'h02); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h4,'h01); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h4,'h03); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h4,'h03); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    P("CNT = phi2/2 4 pulses A2");

    R('h4,'h02); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h00); P("Read TAL");

    R('h4,'h00); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h02); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    P("CNT = phi2/4 4 pulses A2");

    R('h4,'h01); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h4,'h00); P("Read TAL"); //3 delay

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h00); P("Read TAL");

    R('h4,'h00); P("Read TAL");

    R('h4,'h03); P("Read TAL"); // 2 delay

    R('h4,'h03); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h02); P("Read TAL"); // 3 delay

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h02); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h4,'h01); P("Read TAL"); // 3 delay

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h01); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h4,'h00); P("Read TAL"); // 3 delay

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h00); P("Read TAL");

    R('h4,'h00); P("Read TAL");

    R('h4,'h03); P("Read TAL"); // 2 delay

    R('h4,'h03); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h03); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h4,'h02); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h4,'h02); P("Read TAL");

    R('h4,'h01); P("Read TAL");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('h1,'hBF); P("Read PB");

    R('hD,'h9B); P("Read ICR");

    Hi Strik,

    > I am currently having the case the the transfer works for 3 to 5 MB, but every know and then, the transfer stops. To me, it seems that some byte was skipped. That's why what you wrote above sounds very interesting to me.

    Well I've not seen all the details to comment, but in general I'd expect a skipped interrupt then. It could be an as yet unknown bug, like the infamous timer B bug where you read ICR on the exact cycle timer B has an underflow.


    But I'm not aware of any details of the 1570/71/81 so I couldn't say if there is any issue in there somewhere.

    If there is some issue that happens truly randomly in time it might also be caused by meta-stability issues. Then again at these kind of slow speeds that would surprise me.

    Thinking about it a bit more - maybe I'd check the signal integrity coming from the PC side (or what you're using) and flank steepness to see if that couldnt' trigger something twice.

    Then again, I described above my experience with PC using high speed interfacing: you just can't do anything realtime of any sort with PCs. Chipsets also vary too much and have (in some cases poorly understood) timing bugs. So anything on PC would in my opinion need full handshaking. But some type of Arduino inbetween should work just fine.

    You already know the discussion here: Bitte melde dich an, um diesen Link zu sehen.? This is the background for (some of) the VICE test progs.

    Thanks, no I wasn't aware of that thread. From my background, it looks like some internal transistor dimensions difference between IC production batches, cause some CIA batches to have slightly different behaviour when internal drivers are competing. Or something.

    Anyway I'd noticed and implemented the SDR buffering too. The datasheet does mention you can write and keep the buffer filled for continuous transmission.

    I've now been measuring and taking into account the resetting of the SDR shift counter that happens whenever you switch between SPmode input and output - although I've not exhaustively tested those cases yet. Also there is some strange behaviour when you write to SDR while it is in input mode - it seems to skip one input bit in some cases.

    I've observed and am reproducing the behaviour when reading and /or writing twice or more in the same PHI2 high phase to multiple registers. The reason to test and implement this, is that it you get a model much closer to the real thing meaning crazy corner cases are easier to find and reproduce. Like what exactly causes start and stop

    The hardest part still is the Timer A / B behaviour when cycle-accurately reading or writing very close to the timer overflows. For example the exact cycle that the start bit goes to stop when in one-shot mode, or re-starting a timer right before, during or after it stopped. I don't see any other way than exhaustively creating all the test cases one by one.

    I'm still not sure about reproducing the infamous Timer B bug. I see a lot of glitches and strange behaviour - but I've not yet seen a case the ICR skips a Timer B interrupt valid for at least one cycle. I'll try working on that more. Maybe its a combination of 6510 behaviour + 6526

    Hi Paul, thanks for your reply!

    Yes, my understanding is that the CNT pin can be clocked faster than PHI2. I can't remember if I ever did it, though. I think I looked at using it for 64NET for speeding up loading, by allowing the PC to use the shift register to push data over faster than via the parallel interface, but my recollection was that PCs at the time couldn't write to the ISA-connected printer port fast enough to make it beneficia


    Now, as for making a CIA replacement chip, I'd use a cheap Lattice FPGA/CPLD part, some of which I think are already 5V tolerant, and add the necessary level converters. I'd also be tempted to implement the level converters using transistors rather than buffer chips for the IO lines, so that the full behaviour of the pins can be properly implemented. While you need 2 transistors for every IO pin, they are little and could be placed on both sides of the PCB.

    I have actually built a high-speed PC interface back in the day, based off of FCOPY-III, called FCOPY-PC. I remember the serial thing was not working well for me at the time, instead I used the 2 joystick ports to build a 2x 4-bit one-direction connection each with handshake pins. This left the userport free for the 1541 drive. I remember clearly at the time , 486/pentium days that even under MSDOS PCs could no longer run real-time stuff so needed bi-directional full handshaking. It had to do with the caches of the 486/pentiums being stalled whenever you did I/O and/or write to an area not in the cache, so could just be chipset stalling issues.

    Anyway I have tried in extensive tests to get my 6526 to run faster than 1 MHz on the CNT input. I've fount the max speed is 16 phi2 cycles for 1 SDR change, but not in a reliable way.

    What I have learnt from this:

    - You can toggle CNT 1->0->1 or 0->1->0 once, during either low or high phase of phi2. Any single pulse or edge will always be detected.

    - I can count Timer A at a max rate of phi2/2

    - The SDR input register while in input mode can change at a max rate of once per 16 cycles.

    What I conclude from this is that the CNT input is connected to an input S/R latch, which allows a change only to a value different than the value sampled before the last phi2 negedge or posegde (unclear which edge) value. So Set and Reset are both allowed only when different to CNT_RR. (2x delayed)

    I don't observe any anti-metastability type of delay here. Its all still 1 or 2 phi2 phases.

    I imagine this circuit is meant as a type of slow-input-flank detection to prevent against noise. Maybe when examining the silicon W/L it is found the input is a type of Schmitt-trigger trick, where the change of CNT_RR changes the Vth sensitivity of this input latch circuit. That would make CNT very well protected against very slow flank edges from external circuits. Maybe the TOD input has a similar protection, it would probably need it.

    On SDR, when I run at phi2/3 speed I find I can replicate the silicon perfectly, by sampling SP input 3 cycles after the CNT edge. I have setup the testbench to keep SP pin low on all phi2 stages except this 3rd clock and it is taken as a 1. The opposite also works, keep SP 1 for all cycles then 0 just on the 3rd cycle - it is seen as a zero.

    WHen I clock SDR in any faster than CNT three cycles low, three cycles high, then I get unreliable state. Something is still working but not reliably. This must mean the exact internal state is meant to go no faster than 3 cycles (which is 4 cycles of an external part which then could be 3 cycles occasionaly due to clock drift between systems)

    Ive tried looking for replacement parts 5V tolerant - I've not found many good options. Around 280 registers are required, that is more than the CPLDs allow that are still affordable. The only part I've found so far is the Spartan II at maybe 6 USD.

    Using individual FETs is also what I think, given there aren't much better 74xx parts for many individual separate output enables.

    Altough I'll prototype without any FETs. An open-drain solution with pull-up should be fine I hope. Maybe with a very short 10ns pull-high pulse followed then by a regular weak pull-up phase.

    Do you have a specific issue why FET's should be preferred to open-drain with pullup?

    There's already a Project going on at Lemon Forum.

    Search for JCIA. Prototypes are already in beta-testing phase.

    I've seen some information on the J-CIA here Bitte melde dich an, um diesen Link zu sehen.

    But as the IC markings are removed I doubt very much there will be any open hardware coming out of that.

    I've seen a guess on forum64 that the ICs might be an FPGA and two level shifter ICs, but who knows. The middle IC looks like a QFN44 package to me, not sure if any fpgas come in that format. Some MCUs like Atmega32U4 do come in QFN44 though.

    I'd be hoping for a 5V tolerant fpga solution or a MCU based solution using a C model and no further parts to keep cost down. Some less used or unused features might be missing in the end.

    The latest mega65 cia is at Bitte melde dich an, um diesen Link zu sehen., but it is still incomplete.

    You should talk to Gideon, as he has a much more accurate CIA implementation than we have.

    Yes, CNT can count at upto about 16MHz on real CIAs, as has been hinted at above.

    Here is the direct link:

    Bitte melde dich an, um diesen Link zu sehen.

    Hmm I have not seen CNT having an effect twice in one PHI2=1 phase. When I did 0->1->0->1 4x while keeping PHI2=1 it still registers as one count in my test.

    I'd be surprised CNT works at 16MHz, while PHI2=1MHz. Is that really what you're saying? Could be a mistake in my tests then.

    ... also, if you do it in VHDL instead of verilog, we'd love to put an improved CIA in the MEGA65 :)

    Paul.

    Verilog & VHDL are like the indenting wars ... 2, 4 or 8 characters.

    I personally dont like VHDL for the same reasons I don't like Java: Its extreme verboseness, very hard to check if an intended piece of code actually matches the intention.

    So for me its verilog all the way. Once they introduced the always @* construct, I've never looked back.

    Nevertheless, of course I've had to do a lot of VHDL coding too. In the MIST example above I included, there is a reference to a Work debugging library item used in simulation, called to_hstring. The way that has to be implemented in VHDL looks absolutely nothing like the intention of the function, and whatever I did I could not convince Xilinx to skip over this function for synthesis. In the end I resorted to manually commenting out all the report statements.

    Yes as far as I can remember, we used two different types of tools for layout extraction.

    One type is just for LVS, that would be closest to what is needed here, as all wires and capacitances are ignored. You do get the W/L information - which is just the polygon dimension of the actual gate of the transistor - which is needed in some cases like to know if a transistor is used as a weak pull-up or pull-down rather than as a driver.

    This extraction was fast if I recall. A few minutes I remember. I think Magic and other free EDA tools will have versions of that.

    The resulting LVS transistor spice netlist can be converted directly, 1:1, into a switch level verilog netlist for digital simulation - using pmos and nmos verilog primitives. But mostly we would use some tool to assembling inverters/latches etc into higher level cells.

    Then you had the full parasitic extraction, used to then subsequently create static timing analysis. That could take many hours to create and is really highly dependant on technology files, with full resistance and capacitance of all wires. You certainly don't need that detail.

    We would use verilog netlists for checks on IC scan chains to verify the automatically created production level test vectors work correctly. You can annotate the verilog with timing information, but that is not necessary for things like a test vector check. I think the available open source verilog simulators are fast enough for that, for sure, especially for these designs.

    Hi androSID, which tools are you re-inventing ?

    I've not seen much available - the process I found right now online here

    Bitte melde dich an, um diesen Link zu sehen.

    seems to be indeed roughly how we worked when I was IC designer. You set some basic technology parameters, specify the VDD and GND, add the labels for every IO pad, and then let the tool do its job. After that there was another tool that could find cells from the netlist, as long as you provided a set of cells to detect. (inverter, latch and so on)

    I'd imagine the test vectors I'm looking for and building, would be quite useful to check if the extracted netlist does indeed match the silicon.

    Cycle-level test vectors are easily suitable for spice-level simulation.

    What is the part of the work with these free tools you don't like?

    I've found from professional use, all the professional CAD tools really are extremely buggy.

    This doesn't stop people using them, as making your own tools is just too much work and introduces even more bugs. At least with existing tools, you have a set of mostly known bugs and workarounds....

    Would you be interested in some SVG-to-other converer?

    Yes, I'd seen the die shots androSID has posted, they look great, but I'm not sure how to proceed from the die shots.

    I would hope there is some tool to turn die shots into polygon files (one gerber file per layer basically) which can then be fed into some automated transistor schematic generation tool.

    When I was IC designer, we used LVS (Layout-Versus-Schematic) tools that could automatically extract transisitor netlists from gerber files and compare them to the Verilog netlist we'd be trying to implement. Highly specific and very expensive tools (millions of dollars per year) though. But I'd imagine making some extraction netlist tool could be automated.