Affichage des articles dont le libellé est VHDL. Afficher tous les articles
Affichage des articles dont le libellé est VHDL. Afficher tous les articles

mercredi 29 avril 2026

The Z80 CTC: what a poem this thing is!

Over the past few days, I've returned to implementing the Drumulator in an FPGA. I won't go over the whole story again, but after multiple attempts and failures to produce a viable VHDL code for the Z80 CTC, I finally managed to create a 'minimal' version earlier this year (2026), thanks to a 'great' collaboration with AI that began in December 2025.

I knew that even if this time I managed to boot the Drumulator system on the Efinix FPGA board, my code wasn't very good—especially regarding clock domains, not to mention the rather poor operation of the entire channel clock management circuitry.

Confirmation that my 'CTC' wasn't working correctly came when I tried to implement the management of the Drumulator's data potentiometer."


The operation of this system is very simple to understand. The Drumulator initializes a pulse on the 74LS221 circuit. This pulse lasts for a 'certain time', corresponding to the charge of capacitor C77, charged by the current flowing through the potentiometer. This pulse acts as a gate, allowing the CLK.D clock to trigger one of the CTC counters — in this case, counter n°2, since it is connected to the CLK/TRG2 input.

However, this requires a specific programming of CTC channel 2, in counter mode. But that's not enough. The designers at EMU exploited the CTC's characteristics to the fullest. Thus, they fully utilized the operating behavior of the CTC's RESET system.

Last week, I completely rewrote the CTC code, this time fully managing the different clock domains and implementing the entire logistics chain for configuring the channel clocks. Apart from a small issue regarding the trigger edge of the Write signal, everything worked from the start.

But since the CTC is (in my opinion) now properly programmed, every little inaccuracy comes at a cost!

The first issue was initializing the counters to ZERO. I hadn't looked closely at the documentation on this point — well, because it didn't seem like the most important thing. Except that handling ZERO is important. In fact, it's very simple. The counter counts from 256 down to 0. Except that 0 triggers the counter reload and possibly the generation of the channel interrupt. The counter must therefore be 9 bits, not 8, and when you load the value 0x00, you actually need to load 0x100 — easy!

The other problem concerns the CTC's RESET system. Again, it's very simple once understood, but because it's not intuitive, it takes a little time to grasp how it works. It's a rather strange behavior — in any case, it doesn't match at all what one would expect from a 'standard' RESET. Since explaining it here would be a bit long, those who are curious can refer to the CTC documentation.

Since I now have a fairly good command of the Efinix debug tools, I was able to use them to trace the RESET behavior and finally understand where my misunderstanding lay. Now, it's understood."

And the result is:


The Drumulator is in tempo adjustment mode. This is done using the potentiometer stuck between the black and yellow terminals of the breadboard,

It works very well. However, on my breadboard, I powered the logic circuit not with 5V but with 3.3V. As a result, the trigger thresholds are no longer exactly the same. I was able to easily correct the operating range so that the minimum and maximum value ranges correspond correctly to the extreme positions of the potentiometer wiper, simply by adjusting the CLK.D clock that triggers counter n°2. 

Now I have all the technical aspects of the Drumulator implemented. I even have the metronome output! I don't think I will handle synchronization because everything is done via MIDI now. I'm also not going to implement the cassette interface since no one uses it. I'll consider using another backup system instead of the cassette.

I think I'll stop my FPGA-based investigations on the Drumulator for a while. Now I need to create an FPGA core for this Drumulator. I've started designing the printed circuit board. But before moving on to the physical realization of this circuit, I will now finalize the MSX cartridge. It is with this cartridge that I will see whether my Efinix FPGA implementation has been done correctly.

I've been tinkering with FPGAs for years. But I hadn't acquired the general mindset to adopt for programming them. AI was a very good trigger, showing me the way of what needed to be done and what was best to avoid. With this help, I accomplished in 4 months what I hadn't managed to do in over 10 years. Beyond the pleasure of (a small) success, it is also and above all the pleasure of the intellectual groundwork progression that this gave me!

mardi 10 mars 2026

I really like AI!

I really appreciate the support of AI. When I think about the so-called education I received during my schooling! As a result, well, I'm making steady progress with VHDL. A few days ago, I tackled the Zilog SIO. This time, I started without the help of AI, only relying on basic personal knowledge and what I've recently learned thanks to AI's input. The result is an encouraging start in understanding how the SIO works. For now, I'm just getting the source code to work for an 8-bit data serial link, no parity, and one stop bit. The basics, basically. And well, the result is there:
 
 


In fact, this time I'm using AI not to gain a global understanding of the art of programming in VHDL, but to acquire additional syntax for information manipulation. Indeed, even though the RX and TX functions work, everything I've coded obviously includes all the necessary clock domain crossings and all the synchronization processes for the various processes.

It's indeed better to start the code this way because the SIO has different operating modes. For now, I'm dealing with the asynchronous mode, but I'll also need to manage the synchronous mode with flag detection, because that's the mode used on the EMU1 to manage the floppy disk drive.

Just to reliably manage the asynchronous mode, there's still a fair amount of code to generate and also a lot of testing. But still, it's totally satisfying to see the birth of functional VHDL code.

I must also add that, with practice, editing code using the Efinix software's VHDL editor is not the right solution. The main reason is that multi-windowing management is catastrophic. In this respect, what I'm observing aligns perfectly with my idea of development on Windows. Efinix probably uses a framework other than Microsoft's. Consequently, the problems related to that framework are added to those purely related to Windows management.

So I use Zed, which has a plugin for VHDL and can even perform some syntax checking. It's really, really good. I only use the Efinix IDE now to launch its 'standalone' tools, in fact : compilation, the various project configurations, test bench configuration, and using the internal signal analyzer. That way, I no longer have to worry about window inheritance because it's truly a nightmare on Windows, this thing!

mardi 20 janvier 2026

Develop with AI.

A few months ago, I tried to code a ZILOG CTC in VHDL. Indeed, I have a long-term project to implement the Drumulator rhythm box from EMU into an FPGA. Why, you might ask? Well, I really appreciate this machine for its simplicity. Plus, I consider it a good project for this kind of development. I've been coding the core of the machine for a few years. That's not really difficult since it just involves using the code of the Z80 processor called T80, which is directly available as open source. A few lines of combinatorial logic in the FPGA, and the Drumulator boots up. At least, its processor part.

The problem with the story is that all the real-time operation of the machine is managed by a Z80 CTC. During my tests, I simulated the operation of this CTC. Simulating means I ensure the CTC behaves the way I know it should respond. The only problem is that this virtual CTC is not programmable, and in fact, I only use the channel managing the display multiplexing. But anyway, the proof of concept was validated.

Indeed, after testing the analog part of this Drumulator, I decided to tackle this CTC anyway. I did find some VHDL 'codes' for a Z80 CTC on Internet, but I was never able to use them correctly for this Drumulator project. The reason is that these codes were designed to react according to the very specific needs of the people who coded them. In fact, they are not complete Z80 CTC codes.

So, a few months ago, I tried again to create this CTC. But in vain. I did manage to get something working with the display board I specifically developed for the Efinix development board, which features a Trion FPGA, but it was impossible to achieve stable operation of the Drumulator's keyboard/display interface. I ended up abandoning the subject because, on top of that, I lacked the proper tools for debugging the VHDL code.

Since then, I have reused the TRION development system for my MSX cartridge. The goal of this new cartridge implementation was to incorporate a processor directly inside the FPGA to handle file transfers from a PC. So, having used the internal processor provided by Efinix to debug the download process step by step, I thought I could use this internal processor to send stimuli to my CTC VHDL code, while also being able to retrieve the state of this CTC, again through the internal processor, and send the result to a text console. 

If needed, a few lines of VHDL code 'would be' added to allow the visualization of certain signals directly on the development board's LEDs. This therefore seemed like a very compelling possibility for developing and testing VHDL code. However, as I am not a VHDL coding expert, and having spent a considerable amount of time trying to code the CTC in VHDL, I had realized what could be called a mistake, not in analysis, but in the structure of the VHDL code. This made it harder to understand and very complicated to test without the proper tools. And that's where AI comes in.

I then posed what seemed like relevant questions to an AI and refined the subsequent questions to steer this AI in the direction that suited me best. After a few iterations, I realized that the essence of the CTC was there. Furthermore, the code structure was different from what I had personally developed, but this posed no problem for me in understanding its 'intended' functionality at first glance, and also in immediately identifying potential points of failure, and most importantly, for what reasons.

So, I began systematically testing the VHDL code provided by the AI with the help of the internal processor implemented within the FPGA. And, little by little, I first validated the writing to all the CTC registers, then the various selected modes of the CTC's 4 counting channels, and the reading of the registers. And then, inevitably, the time came to test the interrupt system. This is the stage, I believe, where I failed to validate my personal VHDL code developed a few months earlier. And this interrupt management aspect is crucial for the Drumulator, and obviously for all Z80 systems that use vectored interrupts.

I tested all aspects of vectored interrupt generation: the management of the IRQ pin, the interrupt vector, the daisy-chaining of interrupts, the IEI and IEO signals, and, most importantly, the handling of interrupt ACK from the Z80. It's the same as always—nothing is complicated once you understand how the CTC works, but coding everything correctly in VHDL is not that simple, at least for me.

As a result, I was able to start from the source code provided by the AI, modify it, adapt it, and test its functionality step by step as features were implemented. The outcome is that I managed to test 100% of the CTC's VHDL code functionality. However, I must note that I am not using this CTC with a "real" Z80 but with a Z80 simulated externally via the input/output ports of the embedded processor.

Obviously, I coded the I/O behavior of the embedded processor to react exactly as a real Z80 would. Therefore, I cannot say this CTC is 100% validated as being identical to the original CTC, but from a functional standpoint, it is. And I have a strong presumption that it will work with a VHDL Z80 implemented in this same FPGA. However, one should anticipate that there will be some 'edge effects' during the concrete implementation and use of this CTC.

So, what was the contribution of AI in all this? Well, the generated code served as a framework to follow for developing and testing the VHDL code. Paradoxically, the code produced by the AI seems quite clean and, above all, easy to follow. Obviously, where I thought it wouldn't work, it didn't. But I already knew the reason, so I only had to correct it. In fact, the AI doesn't handle different timing domains at all, but that's not a problem when you know how it's supposed to work.

Finally, I have a functional and tested Z80 CTC VHDL code, ready to be used for real with a Z80 also coded in VHDL inside a TRION FPGA. In terms of time spent, I would say the benefit is total. Of course, I have some knowledge of VHDL, as well as logic, programming, electronics, etc., so I wasn't starting from scratch. But in fact, the time spent on this project corresponded to 30% development and 70% testing, which is a very satisfying ratio for me.

Next step in this subject: attempting to get the Drumulator's processor section running, this time with the help of a "real" Z80 CTC.

mercredi 18 mai 2022

Gowin FPGA

 I just received the PCBs for testing the Gowin 144 pin FPGA :

Yes, seen like that, it's not very 'sexy'. But hey, it will be, I hope...