diff --git a/README.md b/README.md index 4f20c7b..147cd76 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,70 @@ TinyTapeout is an educational project that aims to make it easier and cheaper than ever to get your digital designs manufactured on a real chip! This is my submission for TinyTapeout 5 in early November 2023. -A programmable interrupt timer allows you to specify when a digital line is pulled high after a given number of clock ticks, the timer can either repeat or be one-shot. +This design is a programmable interrupt timer allows you to specify when a digital line is pulled high after a given number of clock ticks, the timer can either repeat or be one-shot. -TODO: how to configure the first register -TODO: how to configure the second register, the high byte of the counter -TODO: how to configure the third register, the low byte of the counter. +## Quickstart +The following is pseudocode for can configuring an interrupt pin to go high for one cycle after 10 cycles (plus 2 for setup). + +``` +uio_in = 0xA0 +ui_in = 0xA +``` + +This will set the interrupt timer to be one-shot and set a 8-bit counter of 0xA (integer 10). Wait 12 cycles and then the last pin in `uio_out` will be high. + +## More details + +There are three configuration registers, written to the data held in `ui_in` and selected with the high 3 bits from `uio_in`: + +`uio_in[7]` sets write enable (`WE`), which says the timer is being configured when pulled high. + +The concatenation of `{uio_in[5], uio_in[6]}` selects which register is being written. + +### Register Selection Values + +As previously stated, `{uio_in[5], uio_in[6]}` are the two bits used to select how to configure the timer. The meanings of the four registers are given below: + +* `00` sets the options: divider on and repeating +* `01` sets the high bit +* `10` sets the low bit +* `11` is unused + +### Timer options + +When you select the `00` register, there are two options: + +#### Clock divider + +`divider_on <= ui_in[7];` + +This bit selects whether a 10x clock divider is used. + +## Repeating + +`repeating <= ui_in[6];` + +This bit selects if you want the interrupt to repeat. The default value is for the interrupt to be one-shot. + +## Timer registers + +The registers selected with `01` and `10` each specify which 8-bits of the 16-bit register to set. + +The bits of `01` followed by the bits of `10` determine the full 16-bits of the timer value. `01` does not need to be set if you don't need more than 8-bits but `10` must be set, if only to zero, for the timer to start. + ## Starting the timer. -Configuring the third register is what starts the timer as the other two registers are optional. The default settings if the first register isn't set are to be a one-shot timer with no clock divider. +Configuring the third register (`10`) is what starts the timer as the other two registers are optional. The default settings if the first register isn't set are to be a one-shot timer with no clock divider. -## RTL errata +## Lessons Learned +Programmed IO setup is annoying and I spent a lot of time on it. I think I would prefer to use an SPI ROM or RAM and utilize more of a memory-mapped approach in the future. + +I don't have a lot of tools in my toolbox for squeezing cycles out of a design that leans on registers which leads me to the RTL errata section. + +## RTL errata +No matter how long the timer is set for, there are a few extra cycles due to setup or latching. # Want to see your own digital design taped out to an ASIC? Go to https://tinytapeout.com for instructions! \ No newline at end of file diff --git a/info.yaml b/info.yaml index 2986947..df918a0 100644 --- a/info.yaml +++ b/info.yaml @@ -28,7 +28,7 @@ documentation: # Longer description of how the project works. You can use standard markdown format. how_it_works: | - A minimal clone of a programmable interrupt timer. Inspried by the Intel 8253 but without most of the features or headaches. + A minimal clone of a programmable interrupt timer. Inspried by the Intel 8253 but without most of the features or headaches. See the `README.md` for detailed documentation. # Instructions on how someone could test your project, include things like what buttons do what and how to set the clock if needed how_to_test: |