Why ADD is 4 cycles on Z80? - z80

I use this ALU block diagram as a learning material : http://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html
I am not familiar with electronics. I am currently believing that a clock cycle is needed to move data from registers or latch to another register or latch, eventually throught a net of logical gates.
So here is my understanding of what happens for and ADD :
Cycle 1 : move registers to internal latchs
Cycle 2 : move low nibbles internal latchs to internal result latch (through the ALU)
Cycle 3, in parallell :
move high nibbles internal latchs to destination register (through the ALU)
move internal result latch to register
I think operations cycle 3 are done in parallell because there are two 4 bits bus (for high and low nibbles) and the register bus seems to be 8 bits.

Per the z80 data sheet:
The PC is placed on the address bus at the beginning of the M1 cycle.
One half clock cycle later the MREQ signal goes active. At this time
the address to the memory has had time to stabilize so that the
falling edge of MREQ can be used directly as a chip enable clock to
dynamic memories. The RD line also goes active to indicate that the
memory read data should be enabled onto the CPU data bus. The CPU
samples the data from the memory on the data bus with the rising edge
of the clock of state T3 and this same edge is used by the CPU to turn
off the RD and MREQ signals. Thus, the data has already been sampled
by the CPU before the RD signal becomes inactive. Clock state T3 and
T4 of a fetch cycle are used to refresh dynamic memories. The CPU uses
this time to decode and execute the fetched instruction so that no
other operation could be performed at this time.
So it appears mostly to be about memory interfacing to read the opcode rather than actually doing the addition — decode and execution occurs entirely within clock states T3 and T4. Given that the z80 has a 4-bit ALU, it would take two operations to perform an 8-bit addition. Which likely explains the use of two cycles.

Related

Minimum time between falling and rising edge to detect a rising edge on a GPIO on STM32H7

On my STM32H753 I've enabled an interruption on the rising edge of one of the GPIOs. Once I get the interrupt (provided of course that the handler acknowledges the IT in the EXTI peripheral), when the signal goes low again, I will be able to get another interruption at the following rising edge.
My question is: what is the minimal duration between the falling edge and the rising edge for the latter to be detected by EXTI ? The datasheet specifies many characteristics of the IOs, in particular the voltage values to consider the input low or high but I didn't find this timing.
Thank you
For the electonic part, you need to refere to you MCU datasheet.
However I beleive you need the information about the software part:
You will be able to handle a new GPIO IRQ (EXTI) as soon as you've aknowlegded the former one by clearing the IRQPending Flag or via HAL APIs.
If two IRQs occurred and you did not clear the IRQPending flag yet, then they will be considered as one IRQ. Benchamrking such delay depends on the Clock speed you're using and the complexity of your EXTI_IRQ_Handler routine.

How many I/O interrupts can happen during a time period?

I don't need exact figures but I want to know a realistic sense of the typical average pc's ability to read input interrupts in 1 millisecond period. Say a mouse keeps moving, how many reads happen for an average or a gaming mouse for that matter, by the os?
In other words if we make a program that tries to record mouse inputs, how frequent should we read in order to read a single input value more than once?
This depends on hardware and what kind of device you are talking about. Intel actually provides the maximum rate of interrupt for its xHCI USB controller. I would say this maximum rate is probably too high for any gaming mouse. The Intel document about xHCI (https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf) specifies at page 289 that
Interrupt Moderation allows multiple events to be processed in the context of a single Interrupt Service Request (ISR), rather than generating an ISR for each event.The interrupt generation that results from the assertion of the Interrupt Pending (IP) flag may be throttled by the settings of the Interrupter Moderation (IMOD) register of the associated Interrupter. The IMOD register consists of two 16-bit fields: the Interrupt Moderation Counter (IMODC) and the Interrupt Moderation Interval (IMODI).Software may use the IMOD register to limit the rate of delivery of interrupts to the host CPU. This register provides a guaranteed inter-interrupt delay between the interrupts of an Interrupter asserted by the host controller, regardless of USB traffic conditions.The following algorithm converts the inter-interrupt interval value to the common 'interrupts/sec' performance metric:
Interrupts/sec = (250×10-9sec × IMODI) -1
For example, if the IMODI is programmed to 512, the host controller guarantees the host will not be interrupted by the xHC for at least 128 microseconds from the last interrupt. The maximum observable interrupt rate from the xHC should not exceed 8000 interrupts/sec.Inversely, inter-interrupt interval value can be calculated as:
Inter-interrupt interval = (250×10-9sec × interrupts/sec) -1
The optimal performance setting for this register is very system and configuration specific. An initial suggested range for the moderation Interval is 651-5580 (28Bh -15CCh). The IMODI field shall default to 4000 (1 ms.) upon initialization and reset. It may be loaded with an alternative value by software when the Interrupter is initialized
USB works alongside the xHCI to provide interrupts to the system. I'm not a hardware engineer but I would say that the interrupt speed depends on the mouse frequency. For example this mouse: https://www.amazon.ca/Programmable-PICTEK-Computer-Customized-Breathing/dp/B01G8W30BY/ref=sr_1_4?dchild=1&keywords=usb+gaming+mouse&qid=1610137924&s=electronics&sr=1-4, has a frequency of 125HZ to 1000HZ. It probably means that you will get a interrupt frequency of 125/s to 1000/s since the mouse has this frequency. Its optical sensor will check the surface that the mouse is on at this frequency providing an interrupt for a movement.
As to interrupts themselves, I think it depends on the speed of the CPU. Interrupts are masked for a short amount of time while handling. The fastest the CPU, the fastest the interrupt will be unmasked, the fastest a new interrupt can occur. I would say the bottleneck here is the mouse with 1000 interrupts/s, that is 1 interrupt/ms.

How to set a signal high X-time before rising edge of clock cycle?

I have a signal that checks if the data is available in memory block and does some computation/logic (Which is irrelevant).
I want a signal called "START_SIG" to go high X-time (nanoseconds) before the first rising edge of the clock cycle that is at 10 MHz Frequency. This only goes high if it detects there is data available and does further computation as needed.
Now, how can this be done? Also, I cannot set a delay since this must be RTL Verilog. Therefore, it must be synthensizable on an FPGA (Artix7 Series).
Any suggestions?
I suspect an XY problem, if start sig is produced by logic in the same clock domain as your processing then timing will likely be met without any work on your part (10MHz is dead slow in FPGA terms), but if you really needed to do something like this there are a few ways (But seriously you are doing it wrong!).
FPGA logic is usually synchronous to one or more clocks,generally needing vernier control within a clock period is a sign of doing it wrong.
Use a {PLL/MCM/Whatever} to generate two clocks, one dead slow at 10Mhz, and something much faster, then count the fast one from the previous edge of the 10MHz clock to get your timing.
Use an MCMPLL or such (platform dependent) to generate two 10Mhz clocks with a small phase shift, then gate one of em.
Use a long line of inverter pairs (attribute KEEP (VHDL But verilog will have something similar) will be your friend), calibrate against your known clock periodically (it will drift with temperature, day of the week and sign of the zodiac), this is neat for things like time to digital converters, possibly combined with option two for fine trimming. Shades of ring oscs about this one, but whatever works.

Clock Conversion for RTL Verilog (FPGA) Synthesizable Code

Converting 12 MHz system clock signal on FPGA to 1 MHz Signal output at a 50% duty cycle.
I understand that I need to divide by 2 # 50/50 duty cycle to get 6 MHz, and then divide by 2 again to get to 3 MHz, and then divide by 3 to get to 1 MHz. Is this the correct method?
Also, how would I implement this in RTL Verilog code?
Is this the correct method?
No. First, operating on clocks in logic is often difficult to route appropriately, especially in multiple stages. Second, it is especially difficult to divide a clock by 3 and get a 50% duty cycle without either negative-edge or DDR flip-flops, both of which are often unavailable in FPGA fabric.
The correct method is to use your FPGA's clocking resources. Most modern FPGAs will have one or more onboard DLLs or PLLs which can be used to manage clock signals.
On Xilinx parts, these resources are known as the DCM, PLL, and/or MMCM, and can be instantiated using the ClockGen IP core.
On Altera/Intel parts, these resources can be configured through the PLL and other megafunctions.
On Lattice parts, these resources are known as the sysCLOCK PLL, and can be configured using IPexpress.

PWM using thread

Am modelling an inverter with 5 switches controlled by multi-reference single carrier SPWM. I need to generate pulses for 5 switches at a time using a MATLAB function block. Since it cannot be executed one at a time we need to use parallel programming to which I am new. So please suggest alternatives or parallel programming methods for generating PWM.
The output of the PWM generator is attached
The reference signals had the same frequency and amplitude and were in phase with an offset value that was equivalent to the amplitude of the carrier signal. The reference signals were each compared with the carrier signal.Two reference signals Vref1 and Vref2 will take turns to be compared with the carrier signal at a time. If Vref1 exceeds the peak amplitude of the carrier signal Vcarrier, Vref2 will be compared with the carrier signal until it reaches zero. At this
point onward, Vref1 takes over the comparison process until it exceeds Vcarrier. This will lead to a switching pattern as shown in image. Switches S1- S3 will be switching at the rate of the carrier signal frequency while S4 and S5 will operate at a frequency equivalent to the fundamental frequency.

Resources