Off by one error07/4/2018In the last weeks I did build most remaining boards and did more testing. All registers are available now, and the second ALU board is ready, so the full 16 bit data handling is in place. The new ALU and register cards were first tested with the test device, and the soldering problems that were found were corrected. Then everything was put together. (Only the second Program Counter board, and the keyboard are still missing.) This was too much for my 2A benchtop power supply, it showed the LED's slightly dimming during operations. So I changed to a beefy 24V 10A supply. This was tested:
All tests only worked after one or a few soldering issues were fixed. In the shift unit, one of the diodes (D609) was not connected on the schematic, so a short wire was needed. On the boards with 3 registers, 8 short wires were placed (this was planned), to enable register DH to receive input over the LINK bus (return address). The register pcb uses almost all 96 connector pins. Therefore, the link bus was connected to the output of register C (register C is not placed on these pcbs), and on the pcb there are wires from the register C outputs to the relay coils of register DH. The subroutine call placed the return address in register DH, fine. But when, in the return instruction (LD PC,DH), the DH register is moved to the PC, the PC is incremented before the next instruction is fetched. That means that the instruction after the call is skipped ! A classic off-by-one error. I have not yet decided what to do about this, there are several possibilities. Off by one errorIn the last weeks I did build most remaining boards and did more testing. All registers are available now, and the second ALU board is ready, so the full 16 bit data handling is in place. The new ALU and register cards were first tested with the test device, and the soldering problems that were found were corrected. Then everything was put together. (Only the second Program Counter board, and the keyboard are still missing.) This was too much for my 2A benchtop power supply, it showed the LED's slightly dimming during operations. So I changed to a beefy 24V 10A supply. This was tested:
All tests only worked after one or a few soldering issues were fixed. In the shift unit, one of the diodes (D609) was not connected on the schematic, so a short wire was needed. On the boards with 3 registers, 8 short wires were placed (this was planned), to enable register DH to receive input over the LINK bus (return address). The register pcb uses almost all 96 connector pins. Therefore, the link bus was connected to the output of register C (register C is not placed on these pcbs), and on the pcb there are wires from the register C outputs to the relay coils of register DH. The subroutine call placed the return address in register DH, fine. But when, in the return instruction (LD PC,DH), the DH register is moved to the PC, the PC is incremented before the next instruction is fetched. That means that the instruction after the call is skipped ! A classic off-by-one error. I have not yet decided what to do about this, there are several possibilities. Good progress05/21/2018A few weeks ago, I connected a Raspberry Pi to the program flash memory of the computer. The Raspberry Pi runs the assembler-simulator in its webbrowser. The assembler-simulator has buttons for upload and download from/to the RPi. The RPi is connected with a 16-bit data connection to the Flash program memory, through a small pcb (containing resistors for level conversion). The PROG pcb, that contains the flash chips, also has two 74HC574 registers to store the address for writing the flash. The RPi has a small Phyton program that burns the generated binary in the two Flash memories of the relay CPU. From that moment on, I could run real programs on the computer, although the cpu is only partially built: The data is only 8 bit wide (in stead of 16). Only 4 8-bit registers are present, and it does not run at full speed. Then came several days of serious debugging. Several problems could be fixed by changing the instruction encoding or changing the simulator:
The architecture and instructions document was updated with the encoding changes. Several instructions were working unreliable. All these problems were fixed by changing the hold resistor (2K on the schematics) to 1K5. One non-soldered diode was found. Not all instructions are tested yet, but all tested instructions work now. I made a small demo program that calculates Fibonacci numbers. This weekend, I gave the RISC Relay CPU its own website: RISC Relay CPU Website. Some things on the website might still be a bit quirky. A video of the working computer is on the new website (including sound ;) ! Good progressA few weeks ago, I connected a Raspberry Pi to the program flash memory of the computer. The Raspberry Pi runs the assembler-simulator in its webbrowser. The assembler-simulator has buttons for upload and download from/to the RPi. The RPi is connected with a 16-bit data connection to the Flash program memory, through a small pcb (containing resistors for level conversion). The PROG pcb, that contains the flash chips, also has two 74HC574 registers to store the address for writing the flash. The RPi has a small Phyton program that burns the generated binary in the two Flash memories of the relay CPU. From that moment on, I could run real programs on the computer, although the cpu is only partially built: The data is only 8 bit wide (in stead of 16). Only 4 8-bit registers are present, and it does not run at full speed. Then came several days of serious debugging. Several problems could be fixed by changing the instruction encoding or changing the simulator:
The architecture and instructions document was updated with the encoding changes. Several instructions were working unreliable. All these problems were fixed by changing the hold resistor (2K on the schematics) to 1K5. One non-soldered diode was found. Not all instructions are tested yet, but all tested instructions work now. I made a small demo program that calculates Fibonacci numbers. This weekend, I gave the RISC Relay CPU its own website: RISC Relay CPU Website. Some things on the website might still be a bit quirky. A video of the working computer is on the new website (including sound ;) ! First instructions executed05/05/2018Annoying how slow the progress is if you can not spend enough time on your project.... Just a few days after the last update, I also connected the 8-bit ALU board and the 4x8 bit register board to the motherboard. This should make 8 of the 16 databits and half of the registers operational. I could enter instructions manually with the buttons connected with a flatcable to the PROG pcb (described in previous log). And YES, I could execute several instructions successfully, like addition, saving to RAM, loading from RAM ! I did not test all instructions, but I do not remember an instruction go wrong (that may be selective memory, it's already a few months ago). Anyway, testing branches can not be fully done in this way. The control system will not load the instruction that follows a branch, so that it executes as NOP. But it has no way to prevent me from entering instructions manually... So there is no escaping, it is time for a real program to be run from flash memory. So the next sub-project is a flash memory programmer. I intend to do this with a Raspberry Pi. It can connect to my website that provides the javascript assembler. It could simply write the object code to its own filesystem, and then a Python program could program the parallel flash through RPi I/O. The javascript SIMAS (simulator-assembler) had an annoying 'feature', it did run quite slow. I examined it, and found that for small programs it was OK but with longer assembly programs it became slow. I suspected the Angular framework code. So I threw that out, I didn't understand it very well anyway. But it did not help. Then I switched from Chrome to FireFox, and suddenly the speed problem was gone... I don't know why. But I'm not interested in investigating it further. There are enough other things to do. The SIMAS ( simulator-assembler ) had one of the first versions of the instruction set. So I updated it to the newest instruction set. It has two memory spaces now (program and data). To have initialized data, the assembler simply copies the first few hundred bytes of program space to the data space. This is something that a real program will have to do itself. The layout of the program was also changed. The left side of the screen now has a textfield for entering your program. The center has a bigger textfield, that shows the source code together with the assembled machine code. And the nicest feature... in the center window, all program lines that were executed get a blue background, and the current line after the program halted is red. So the blue background shows you the execution path that the software has taken after the last keypress of the calculator. The buttons that simulate the calculator were re-ordered, to be similar to the pcb that I designed for the keyboard a few months ago. Finally, I worked on the calculator application. It will now do all functions, except the trigonometry functions. The latest code is now automatically loaded when you load the webpage. You can try it at www.enscope.nl/rrca Before operating the calculator, first press "Assemble" and then "Run". I updated the HAD file section. The architecture and instruction listing are now in a single document. The schematics are updated and are according to the pcb's. Gerbers of the pcb's are also provided. First instructions executedAnnoying how slow the progress is if you can not spend enough time on your project.... Just a few days after the last update, I also connected the 8-bit ALU board and the 4x8 bit register board to the motherboard. This should make 8 of the 16 databits and half of the registers operational. I could enter instructions manually with the buttons connected with a flatcable to the PROG pcb (described in previous log). And YES, I could execute several instructions successfully, like addition, saving to RAM, loading from RAM ! I did not test all instructions, but I do not remember an instruction go wrong (that may be selective memory, it's already a few months ago). Anyway, testing branches can not be fully done in this way. The control system will not load the instruction that follows a branch, so that it executes as NOP. But it has no way to prevent me from entering instructions manually... So there is no escaping, it is time for a real program to be run from flash memory. So the next sub-project is a flash memory programmer. I intend to do this with a Raspberry Pi. It can connect to my website that provides the javascript assembler. It could simply write the object code to its own filesystem, and then a Python program could program the parallel flash through RPi I/O. The javascript SIMAS (simulator-assembler) had an annoying 'feature', it did run quite slow. I examined it, and found that for small programs it was OK but with longer assembly programs it became slow. I suspected the Angular framework code. So I threw that out, I didn't understand it very well anyway. But it did not help. Then I switched from Chrome to FireFox, and suddenly the speed problem was gone... I don't know why. But I'm not interested in investigating it further. There are enough other things to do. The SIMAS ( simulator-assembler ) had one of the first versions of the instruction set. So I updated it to the newest instruction set. It has two memory spaces now (program and data). To have initialized data, the assembler simply copies the first few hundred bytes of program space to the data space. This is something that a real program will have to do itself. The layout of the program was also changed. The left side of the screen now has a textfield for entering your program. The center has a bigger textfield, that shows the source code together with the assembled machine code. And the nicest feature... in the center window, all program lines that were executed get a blue background, and the current line after the program halted is red. So the blue background shows you the execution path that the software has taken after the last keypress of the calculator. The buttons that simulate the calculator were re-ordered, to be similar to the pcb that I designed for the keyboard a few months ago. Finally, I worked on the calculator application. It will now do all functions, except the trigonometry functions. The latest code is now automatically loaded when you load the webpage. You can try it at www.enscope.nl/rrca Before operating the calculator, first press "Assemble" and then "Run". I updated the HAD file section. The architecture and instruction listing are now in a single document. The schematics are updated and are according to the pcb's. Gerbers of the pcb's are also provided. Assembling and testing pcb's12/30/2017Around two weeks ago I ordered all remaining pcb's and a lot of parts. They arrived just in time for some happy soldering in the days after Christmas. Each pcb was (sometimes partially) built and then it's main functions were tested, revealing soldering errors but also a few design errors. This is the state today (click it for bigger version): 1) clock and control pcb 2) program counter pcb (6 bits) 3) instruction decoder pcb (only it's LED's are visible) 4) program memory and instruction register pcb 5) RUN button 6) STOP button The pcb's are connected to the main pcb with DIN41612 connectors. I started with the program memory and instruction decoder. (All pcb's in this project were intended to have a white color, but apparently I forgot to select the color when I uploaded the gerbers of this pcb). The flash memory itself is not yet assembled. There is a connector (where the ribbon cable connects) that is intended to connect to a flash memory programmer. It is now connected to 16 pushbuttons, to control the contents of the instruction register manually. The instruction register worked (but several of the 2K2 resistors in the hold circuits had to be lowered in value, apparently the current was not enough to keep the relays attracted). Next was the clock and control pcb. The clock circuit did not work as expected and had to be modified. Two 100uF elco's (visible on top of the pcb) set the clock to approx. 5 instructions per second, slow enough to have a sense of what is going on during testing. Asymmetry in the clock signal will have to be solved (and higher speed will be set at a later time). One of the board's input signals was not connected, a wire was needed to correct this. Another problem: The single-step button should start executing one instruction and then stop. Unfortunately, the stop function works too well, so much that pressing the single step a second time does not run a next instruction... The program counter pcb also has decoders for reading and writing to the registers. Only the program counter section was mounted for now. After re-soldering a resistor, I started the clock and watched the PC counting... 0, 1, 2, 4, 8, 16 .... Oh what's wrong ? Did I build a shift register instead of a counter ? After following the signals on several wires, it occurred to me. The PC has a master and a slave section, they each have a CLR signal. If one of the registers is not cleared, the bits stay 1 and you get this behaviour. This is not visible on the LED's if the leds are connected to the slave section and the non-cleared part is the master section. Well, the CLR of the master could be interrupted by relay RL341, and that was not placed because it was considered part of the decoder section. After placing RL341, it was happy counting ! Now the instruction decoder. It has led's that show the addressing mode ( Memory, Zero page, Immediate, register, test-and-branch) and the instruction ( LD, ADD, AND, OR, XOR ) and a few other output signals. This was simply tested by letting the clock run and manually put something in the instruction register. Many instructions could be tested this way. It revealed an error in the decoding for the DMPY instruction, were inputs to a diode gate had to be connected to IR_Y0 instead of IR_Y0_N. This diode gate was on the pcb with the instruction register, leading to a small modification there. For a LD instruction, also the OR led was on, could be corrected with an extra diode. The led for the PC was connected to a wrong point, not changed yet. Some changes were made in the schematics and pcb design files before they were ordered, so the file section is no longer uptodate. One of the changes was another change in the instruction set... New instructions to subtract two registers without storing the result, providing compare instructions. Logic instructions (and, or, xor) were removed from the register mode and added to the zero-page mode. Documentation will be updated soon. A good 2018 to all of you ! Assembling and testing pcb'sAround two weeks ago I ordered all remaining pcb's and a lot of parts. They arrived just in time for some happy soldering in the days after Christmas. Each pcb was (sometimes partially) built and then it's main functions were tested, revealing soldering errors but also a few design errors. This is the state today (click it for bigger version): 1) clock and control pcb 2) program counter pcb (6 bits) 3) instruction decoder pcb (only it's LED's are visible) 4) program memory and instruction register pcb 5) RUN button 6) STOP button The pcb's are connected to the main pcb with DIN41612 connectors. I started with the program memory and instruction decoder. (All pcb's in this project were intended to have a white color, but apparently I forgot to select the color when I uploaded the gerbers of this pcb). The flash memory itself is not yet assembled. There is a connector (where the ribbon cable connects) that is intended to connect to a flash memory programmer. It is now connected to 16 pushbuttons, to control the contents of the instruction register manually. The instruction register worked (but several of the 2K2 resistors in the hold circuits had to be lowered in value, apparently the current was not enough to keep the relays attracted). Next was the clock and control pcb. The clock circuit did not work as expected and had to be modified. Two 100uF elco's (visible on top of the pcb) set the clock to approx. 5 instructions per second, slow enough to have a sense of what is going on during testing. Asymmetry in the clock signal will have to be solved (and higher speed will be set at a later time). One of the board's input signals was not connected, a wire was needed to correct this. Another problem: The single-step button should start executing one instruction and then stop. Unfortunately, the stop function works too well, so much that pressing the single step a second time does not run a next instruction... The program counter pcb also has decoders for reading and writing to the registers. Only the program counter section was mounted for now. After re-soldering a resistor, I started the clock and watched the PC counting... 0, 1, 2, 4, 8, 16 .... Oh what's wrong ? Did I build a shift register instead of a counter ? After following the signals on several wires, it occurred to me. The PC has a master and a slave section, they each have a CLR signal. If one of the registers is not cleared, the bits stay 1 and you get this behaviour. This is not visible on the LED's if the leds are connected to the slave section and the non-cleared part is the master section. Well, the CLR of the master could be interrupted by relay RL341, and that was not placed because it was considered part of the decoder section. After placing RL341, it was happy counting ! Now the instruction decoder. It has led's that show the addressing mode ( Memory, Zero page, Immediate, register, test-and-branch) and the instruction ( LD, ADD, AND, OR, XOR ) and a few other output signals. This was simply tested by letting the clock run and manually put something in the instruction register. Many instructions could be tested this way. It revealed an error in the decoding for the DMPY instruction, were inputs to a diode gate had to be connected to IR_Y0 instead of IR_Y0_N. This diode gate was on the pcb with the instruction register, leading to a small modification there. For a LD instruction, also the OR led was on, could be corrected with an extra diode. The led for the PC was connected to a wrong point, not changed yet. Some changes were made in the schematics and pcb design files before they were ordered, so the file section is no longer uptodate. One of the changes was another change in the instruction set... New instructions to subtract two registers without storing the result, providing compare instructions. Logic instructions (and, or, xor) were removed from the register mode and added to the zero-page mode. Documentation will be updated soon. A good 2018 to all of you ! All design work has been done !10/14/2017All schematics and pcb designs are finished now. But I will do several checks before I send the PCB's out for production. (I already found some mistakes, can you find them too ?) Today I uploaded in the file section:
This info should be enough to understand the design. I also posted the number of main components (327 relays). On the MEM pcb, I used BAW56 double-diodes because 1N4148 would cost me too much pcb area. All design work has been done !All schematics and pcb designs are finished now. But I will do several checks before I send the PCB's out for production. (I already found some mistakes, can you find them too ?) Today I uploaded in the file section:
This info should be enough to understand the design. I also posted the number of main components (327 relays). On the MEM pcb, I used BAW56 double-diodes because 1N4148 would cost me too much pcb area. Speed limit !06/10/2017Time to check the maximum reachable speed ! The CPU needs 4 clock signals:
There are also phase 2 and phase 4, but they have no clock signal, these phases are the relay 'layers' that follow the state of the relays that are switched by state 1 and 3. As the name implies, a CLR pulse clears a relay, and an Activate pulse can set a relay (if its input signal is true). But the CLR only disables the hold circuit of the relay. At the same time, the activate signal can be busy setting the relay, and even the circuits that follow the relay can already start switching while the CLR is still active ! So the clearing of a relay does not take time because it takes place at the same time as the activation (see technology file in the file section). The phase 1 CLR pulse falls within the phase 1 Activate pulse (so CLR can only be active if Activate is also active). And also, the phase 3 CLR pulse falls within phase 3 Activate. I did built a clock generator that has 4 relays (one for each clock signal), driven by a few transistors, and the transistors driven by a function generator. I attached the new clock to my test-setup (that has an ALU and a Register pcb). Phase 3 loads the ALU latch A with the data from register D, and phase 1 loads register D with the ALU output. On the test pcb, setting function to ADD and loading 1 in ALU latch B. This lets the ALU increment at each clock pulse. Well thats nice... what they call blinkenlights.... see the bytes incrementing at 3 places: at the ALU output, in register D, and at ALU input A. Yes and that sound.... Ohhhh... Cranking the frequency up, until errors begin to occur.... then a little bit down again where everything seems ok.... 136 Hz !! Power consumption around 600mA at 24 Volt. It's not really optimized for watts per megahertz.... The other circuits in the CPU ( like instruction decoder, and PC incrementer ) will operate concurrently, and have the same technology as the ALU and registers (so they will reach the same speed). Most instructions use a single cycle, so the CPU could reach a speed of 136 instructions per second ! Probably will have to run it slightly slower for good reliability. The used relays have 2 mSec operating time. Relays with 1 mSec exist ( like IM06N ) but I found these too expensive. These could double the speed.... Speed limit !Time to check the maximum reachable speed ! The CPU needs 4 clock signals:
There are also phase 2 and phase 4, but they have no clock signal, these phases are the relay 'layers' that follow the state of the relays that are switched by state 1 and 3. As the name implies, a CLR pulse clears a relay, and an Activate pulse can set a relay (if its input signal is true). But the CLR only disables the hold circuit of the relay. At the same time, the activate signal can be busy setting the relay, and even the circuits that follow the relay can already start switching while the CLR is still active ! So the clearing of a relay does not take time because it takes place at the same time as the activation (see technology file in the file section). The phase 1 CLR pulse falls within the phase 1 Activate pulse (so CLR can only be active if Activate is also active). And also, the phase 3 CLR pulse falls within phase 3 Activate. I did built a clock generator that has 4 relays (one for each clock signal), driven by a few transistors, and the transistors driven by a function generator. I attached the new clock to my test-setup (that has an ALU and a Register pcb). Phase 3 loads the ALU latch A with the data from register D, and phase 1 loads register D with the ALU output. On the test pcb, setting function to ADD and loading 1 in ALU latch B. This lets the ALU increment at each clock pulse. Well thats nice... what they call blinkenlights.... see the bytes incrementing at 3 places: at the ALU output, in register D, and at ALU input A. Yes and that sound.... Ohhhh... Cranking the frequency up, until errors begin to occur.... then a little bit down again where everything seems ok.... 136 Hz !! Power consumption around 600mA at 24 Volt. It's not really optimized for watts per megahertz.... The other circuits in the CPU ( like instruction decoder, and PC incrementer ) will operate concurrently, and have the same technology as the ALU and registers (so they will reach the same speed). Most instructions use a single cycle, so the CPU could reach a speed of 136 instructions per second ! Probably will have to run it slightly slower for good reliability. The used relays have 2 mSec operating time. Relays with 1 mSec exist ( like IM06N ) but I found these too expensive. These could double the speed.... Main board layout05/13/2017Still working on the schematics. A lot of little details must be handled:
The last point has great influence on the routing of the main board. So, the main board is routed first. The connector allocation can still be changed if needed (except for the existing register and ALU pcbs). Here is the current status: There are two rows of 6 connectors. At the front, there are 12 displays. The yellow signals must still be routed. But there will be more to do, since the schematics are not complete yet. This will keep me busy for a while... The ALU has now all 8 bits built, and is working after solving a few soldering issues. Main board layoutStill working on the schematics. A lot of little details must be handled:
The last point has great influence on the routing of the main board. So, the main board is routed first. The connector allocation can still be changed if needed (except for the existing register and ALU pcbs). Here is the current status: There are two rows of 6 connectors. At the front, there are 12 displays. The yellow signals must still be routed. But there will be more to do, since the schematics are not complete yet. This will keep me busy for a while... The ALU has now all 8 bits built, and is working after solving a few soldering issues. PCB's for ALU and registers04/16/2017The first two PCB's have arrived ! This is the pcb for the registers:
The pcb implements four 8-bit registers (registers C, D, X, Y). Only 8 bits (4 bits in 2 registers) are mounted. At the topside of the PCB, you see that each register has its own 8 LED's to indicate the contents. The pcb is labeled "REG1710" (top left) meaning the design is from 2017 week 10. The other PCB is the 8-bit ALU "ALU1710":
Only 4 bits of the 8-bit ALU are mounted. The 4x4 relay section is the basic ALU, that includes two input registers (latches, to be honest). The sections with 2 relays are for the ADD-6 section and decimal correction. On the top of the pcb you see LEDs for input data, output data, function selection and flags. The ALU has the normal Load, AND, OR, XOR, binary ADD, but can also ADD decimally and convert BCD data to 7-segment display code. Subtraction needs help from outside of the ALU. It is done by inverting one of the register outputs (and setting the CY-input). The placement system is all diodes and relays on top, and the resistors on the bottom. Relays are surface mount types, this gives more space for routing at the bottom. Diodes are through-hole 1N4148. I did not use BAV99 or other SOT23 types (otherwise I could be accused of using transistors secretly ;). Mini-Melf were also avoided since they tend to roll away when you try to solder them. Some signal wires drive many circuits, in that case the diode is 1N4004 or similar.
Of course, something was wrong. The connector DIN41612 was not close enough to the edge of the pcb (placement was based on the silkscreen of the footprint, I interpreted one of the silkscreen lines as the edge of the pcb, but that was wrong). I had to remove about 1mm of the pcb to make it fit. This destroyed only a few traces, that must be replaced by a wire. Schematics and gerbers of REG1710 and ALU1710 are in the Hackaday files section. I did built a simple test device. The ALU and REG pcb's can be connected to it. The 3x4 buttons transfer data from a register to the input A of the ALU and from the ALU to a register. The 8 buttons on top control data on input B (next to it are a CLR input B button and a CY-input button). The big knob selects one of the ALU functions, the function is displayed by one of the green LEDs.
For the curious readers, here is the bottom side of the test device:
And of couse, I tested my new pcb's. Found a small problem: It was
intended that all diodes point in the same direction. But a few diodes on the ALU
picked an older diode footprint, that had the silkscreen in the other direction.
The result was a few diodes had to be reversed. After that was done, all assembled functions were working ! (But the tester does not test the second output ports of the registers). Some new instructions were added to the instruction set: - An instruction to load data from the program memory. The simulator has a unified memory, so the instruction was not needed there. - Added XOR with immediate value - Added a powerful instruction: Test a bit and branch. Within a single instruction, a single bit from a register pair can be tested, and a branch forward is done if the bit is 1 (or 0). In each register pair, the bits that can be tested are 0, 1, 2, 3, 4, 7, 15, 31. So this also replaces the clumsy sequence that was needed to test the upper bit of a value in a register. Instead of adding to the PC, this instruction can also conditionally add to register C. The branch forward has a reach of 31. In the instruction space, some space in the register-mode was sacrificed to make the test-and-branch possible. Work will continue with the details of the control functions, and planning the "backplane". PCB's for ALU and registersThe first two PCB's have arrived ! This is the pcb for the registers:
The pcb implements four 8-bit registers (registers C, D, X, Y). Only 8 bits (4 bits in 2 registers) are mounted. At the topside of the PCB, you see that each register has its own 8 LED's to indicate the contents. The pcb is labeled "REG1710" (top left) meaning the design is from 2017 week 10. The other PCB is the 8-bit ALU "ALU1710":
Only 4 bits of the 8-bit ALU are mounted. The 4x4 relay section is the basic ALU, that includes two input registers (latches, to be honest). The sections with 2 relays are for the ADD-6 section and decimal correction. On the top of the pcb you see LEDs for input data, output data, function selection and flags. The ALU has the normal Load, AND, OR, XOR, binary ADD, but can also ADD decimally and convert BCD data to 7-segment display code. Subtraction needs help from outside of the ALU. It is done by inverting one of the register outputs (and setting the CY-input). The placement system is all diodes and relays on top, and the resistors on the bottom. Relays are surface mount types, this gives more space for routing at the bottom. Diodes are through-hole 1N4148. I did not use BAV99 or other SOT23 types (otherwise I could be accused of using transistors secretly ;). Mini-Melf were also avoided since they tend to roll away when you try to solder them. Some signal wires drive many circuits, in that case the diode is 1N4004 or similar.
Of course, something was wrong. The connector DIN41612 was not close enough to the edge of the pcb (placement was based on the silkscreen of the footprint, I interpreted one of the silkscreen lines as the edge of the pcb, but that was wrong). I had to remove about 1mm of the pcb to make it fit. This destroyed only a few traces, that must be replaced by a wire. Schematics and gerbers of REG1710 and ALU1710 are in the Hackaday files section. I did built a simple test device. The ALU and REG pcb's can be connected to it. The 3x4 buttons transfer data from a register to the input A of the ALU and from the ALU to a register. The 8 buttons on top control data on input B (next to it are a CLR input B button and a CY-input button). The big knob selects one of the ALU functions, the function is displayed by one of the green LEDs.
For the curious readers, here is the bottom side of the test device:
And of couse, I tested my new pcb's. Found a small problem: It was
intended that all diodes point in the same direction. But a few diodes on the ALU
picked an older diode footprint, that had the silkscreen in the other direction.
The result was a few diodes had to be reversed. After that was done, all assembled functions were working ! (But the tester does not test the second output ports of the registers). Some new instructions were added to the instruction set: - An instruction to load data from the program memory. The simulator has a unified memory, so the instruction was not needed there. - Added XOR with immediate value - Added a powerful instruction: Test a bit and branch. Within a single instruction, a single bit from a register pair can be tested, and a branch forward is done if the bit is 1 (or 0). In each register pair, the bits that can be tested are 0, 1, 2, 3, 4, 7, 15, 31. So this also replaces the clumsy sequence that was needed to test the upper bit of a value in a register. Instead of adding to the PC, this instruction can also conditionally add to register C. The branch forward has a reach of 31. In the instruction space, some space in the register-mode was sacrificed to make the test-and-branch possible. Work will continue with the details of the control functions, and planning the "backplane". Schematics of 3 PCBs12/18/2016There was not much progress the last months, mostly because of my new project called NeuronZoo ! NeuronZoo is an 'Online 3D simulation of hypothetical programmable brain cells'. Yes. I have new ideas now about the distribution over several pcb's. Each pcb will have a DIN41612 96-pin connector to a backplane. For several subsystems, it is very easy to get over 96 signals, so reshuffling was needed. Also there is a limit to the number of relays that will fit on a pcb, the maximum is now 40. The size of the pcb's will be approx 10 x 14 cm.
For pcb's 1,2 and 3 I did put complete schematics in the Hackaday file section. The PCB design is almost complete for registers and pc/decoder, and halfway for the ALU. The instruction set was again changed. Only half of the registers had logic instructions, this turned out to be impractical. Now, all registers have the same instructions. The price to be paid for this was that conditional instructions are now only for the PC and not for other registers (The ARM-like conditional instruction were not needed so much). Schematics of 3 PCBsThere was not much progress the last months, mostly because of my new project called NeuronZoo ! NeuronZoo is an 'Online 3D simulation of hypothetical programmable brain cells'. Yes. I have new ideas now about the distribution over several pcb's. Each pcb will have a DIN41612 96-pin connector to a backplane. For several subsystems, it is very easy to get over 96 signals, so reshuffling was needed. Also there is a limit to the number of relays that will fit on a pcb, the maximum is now 40. The size of the pcb's will be approx 10 x 14 cm.
For pcb's 1,2 and 3 I did put complete schematics in the Hackaday file section. The PCB design is almost complete for registers and pc/decoder, and halfway for the ALU. The instruction set was again changed. Only half of the registers had logic instructions, this turned out to be impractical. Now, all registers have the same instructions. The price to be paid for this was that conditional instructions are now only for the PC and not for other registers (The ARM-like conditional instruction were not needed so much). Instruction decoder05/24/2016In this log I give some schematic info. I will explain the principles of the instruction decoder. (The ALU and registers are already discussed in one of the files). In the HAD files section, the schematic RRC1613.pdf is a “summary” of the total design. There may be differences between the descriptions. It is hard to keep everything in sync as long as the design is not yet final. Above the long line of RRC1613.pdf, you see the data path essentials for 1 bit (register and ALU). Below the line, the essentials of the instruction decoder are shown. The schematic is intented to give an overview of the polarities and pull-up/pull-down capabilities of the signals. The clocking is not yet in the drawing. For every instruction there are four phases:
Phase 2 and 4 are not clocked, they are are direct result of the actions of phase 1 and 3.
Y0 Y1 mode zpage/immediate/memory/register The upper contacts of these relays are for the hold function, and deliver the signal
(sometimes also in inverted version) for further decoding. Actions for decoding phase 2 and 3 of the instruction: The lower contacts of
these relays are for decoding that has to take place immediately (to decide what data to
put in ALU A and B registers) Relays A1 A0 select 1 of 3 registers at output port 2 (via lowest contacts in the register bank,
with pull-up signals "to_addr"). ( The architecture doc specifies 4 address registers,
but the implementation has only 3.) Relays "A0 slave" and "subtract" select 1 of 2 register pairs (register X or Y) for register mode on port 2 (it uses pull-down signals). The register pair is 32 bits, the shifter selects 16 bits out of these 32 bits (in 4 bit increments). The subtract relay chooses between normal or inverted output at port 2. "A0 slave" means that this register has the same function/state as relay A0, and it is controlled by a contact of A0 so it switches a little later than A0 itself. This is no problem here because the shifter does not introduce a delay, so the register data will be in time to be loaded into the ALU_B register. But when A1 and A0 select an address we can not use a slave register, because there is an extra relay level for address decoding (for capacitor-RAM or diode-ROM, not needed in the case of solid state memory). After the address has been decoded, the data will be immediately available to be loaded in the ALU_B register. A capacitor RAM will be
similar to Rory Mangles TIM8 design. Refresh will be different, the idea is that after the
cap has activated the relay, it will immediately be refreshed through the hold function of
the relay. The circuit of the caps will be such that there is no need to switch between
discharge and charge. Actions for decoding phase 4 and 1 of the instruction: Decoding for phase 2 is less difficult, because there is time for 2 extra relay levels. At the left side you see the ALU-function signals F3, F2, F1, CY-enable, decimal, Carry-in. When all these relays are inactive, the LOAD function is selected as default. For a ADD function, the relays are set for logic XOR (F1 and F2 active) and CY-enable. For decimal ADD, the same is selected, and in this case also "decimal" is activated, to enable decimal correction in the ALU. ( For decimal ADD, in phase 1 the ADD-6 function is activated). For logic
functions, F1, F2 and F3 are set to correct position. Incrementing
the PC is not yet in the schematic. The incremented PC is always written back to the PC,
except when the ALU delivers the new PC contents (in case of a branch or jump). Instruction decoderIn this log I give some schematic info. I will explain the principles of the instruction decoder. (The ALU and registers are already discussed in one of the files). In the HAD files section, the schematic RRC1613.pdf is a “summary” of the total design. There may be differences between the descriptions. It is hard to keep everything in sync as long as the design is not yet final. Above the long line of RRC1613.pdf, you see the data path essentials for 1 bit (register and ALU). Below the line, the essentials of the instruction decoder are shown. The schematic is intented to give an overview of the polarities and pull-up/pull-down capabilities of the signals. The clocking is not yet in the drawing. For every instruction there are four phases:
Phase 2 and 4 are not clocked, they are are direct result of the actions of phase 1 and 3.
Y0 Y1 mode zpage/immediate/memory/register The upper contacts of these relays are for the hold function, and deliver the signal
(sometimes also in inverted version) for further decoding. Actions for decoding phase 2 and 3 of the instruction: The lower contacts of
these relays are for decoding that has to take place immediately (to decide what data to
put in ALU A and B registers) Relays A1 A0 select 1 of 3 registers at output port 2 (via lowest contacts in the register bank,
with pull-up signals "to_addr"). ( The architecture doc specifies 4 address registers,
but the implementation has only 3.) Relays "A0 slave" and "subtract" select 1 of 2 register pairs (register X or Y) for register mode on port 2 (it uses pull-down signals). The register pair is 32 bits, the shifter selects 16 bits out of these 32 bits (in 4 bit increments). The subtract relay chooses between normal or inverted output at port 2. "A0 slave" means that this register has the same function/state as relay A0, and it is controlled by a contact of A0 so it switches a little later than A0 itself. This is no problem here because the shifter does not introduce a delay, so the register data will be in time to be loaded into the ALU_B register. But when A1 and A0 select an address we can not use a slave register, because there is an extra relay level for address decoding (for capacitor-RAM or diode-ROM, not needed in the case of solid state memory). After the address has been decoded, the data will be immediately available to be loaded in the ALU_B register. A capacitor RAM will be
similar to Rory Mangles TIM8 design. Refresh will be different, the idea is that after the
cap has activated the relay, it will immediately be refreshed through the hold function of
the relay. The circuit of the caps will be such that there is no need to switch between
discharge and charge. Actions for decoding phase 4 and 1 of the instruction: Decoding for phase 2 is less difficult, because there is time for 2 extra relay levels. At the left side you see the ALU-function signals F3, F2, F1, CY-enable, decimal, Carry-in. When all these relays are inactive, the LOAD function is selected as default. For a ADD function, the relays are set for logic XOR (F1 and F2 active) and CY-enable. For decimal ADD, the same is selected, and in this case also "decimal" is activated, to enable decimal correction in the ALU. ( For decimal ADD, in phase 1 the ADD-6 function is activated). For logic
functions, F1, F2 and F3 are set to correct position. Incrementing
the PC is not yet in the schematic. The incremented PC is always written back to the PC,
except when the ALU delivers the new PC contents (in case of a branch or jump). Programming logarithms05/22/2016I've been busy with the log(x) function. It works quite nice, see CALC_6.TXT. The simulator counts the cycles between key presses, the log function takes 271 cycles for log(2) . The ln(x) is calculated with the log function, as log(x) * ln(10). This is slower because the general multiply function is used after the log(x). The ln(2) takes 413 cycles. (So to reach my 10-second calculation goal, at least more than 40 instructions per second must be executed). A faster, native ln(x) was also built but abandoned, to save program space. The 10^x function is also in CALC_6, but is not yet accurate enough and only handles a small range at this time. After the sin/cos/tan functions are also available, I will put the program in the logisim simulator to test everything on the gate level (eh.... coil and contact level). And about the hardware.... it is expected to have approx. 270 DPDT relays. Programming logarithmsI've been busy with the log(x) function. It works quite nice, see CALC_6.TXT. The simulator counts the cycles between key presses, the log function takes 271 cycles for log(2) . The ln(x) is calculated with the log function, as log(x) * ln(10). This is slower because the general multiply function is used after the log(x). The ln(2) takes 413 cycles. (So to reach my 10-second calculation goal, at least more than 40 instructions per second must be executed). A faster, native ln(x) was also built but abandoned, to save program space. The 10^x function is also in CALC_6, but is not yet accurate enough and only handles a small range at this time. After the sin/cos/tan functions are also available, I will put the program in the logisim simulator to test everything on the gate level (eh.... coil and contact level). And about the hardware.... it is expected to have approx. 270 DPDT relays. First programming05/16/2016Started programming in the new assembler.... it didn't go very fast. One of the reasons was, that there were still some bugs in the assembler and simulator. Also I made some changes in the instruction set because some features were missing, like a bit test instruction (TSTB). The CL, DL and DH registers were given more functions, at the cost of functions for the X and Y registers. Floating point number entry was more difficult than floating point multiply.... Next thing that I will do, is make LOG and 10^x functions. (I will use the method of An Wang, inventor of the LOCI calculator). First programmingStarted programming in the new assembler.... it didn't go very fast. One of the reasons was, that there were still some bugs in the assembler and simulator. Also I made some changes in the instruction set because some features were missing, like a bit test instruction (TSTB). The CL, DL and DH registers were given more functions, at the cost of functions for the X and Y registers. Floating point number entry was more difficult than floating point multiply.... Next thing that I will do, is make LOG and 10^x functions. (I will use the method of An Wang, inventor of the LOCI calculator). Javascript-online-assembler-and-simulator04/24/2016I have made an assembler and simulator in Javascript, (I modified the assembler-simulator from Marco Schweighauser). The simulator includes a calculator display and keys. You can download it from the file list, or try it online at: www.enscope.nl/rrca The first program is a 8-digit calculator that can only add. You can paste the following code in the online assembler, assemble it and start the simulator. ; CPU simulator test. ; Only calculates: A + B = NOP ;first instruction is skipped ! clr: plus: LDL Y,X ; save X in Y (32 bit) SUBL X,X ; clr X (32 bit) waitkey: HLT ; wait for button press ; HLT ; option for switching to single step TEQ CL,'+' BRZ plus TEQ CL,'=' BRZ result TEQ CL,' ' ; CLR pressed ? BRZ clr ADD CL,0xffd0 ; keep digit code (subtr 0x30) ADDL X,X ; shift X one digit left ADDL X,X ADDL X,X ADDL X,X ADD XL,CL ; add new digit at the right side BR waitkey NOP ; delay slot: the instruction after BR is also executed ! result: DADDL X,Y ; 32-bit decimal add (Decimal ADD Long) BR waitkey
After a calculation, press the "clr" button before a new calculation is started. Change the code and build your own calculator online ! You can also use scientific notation: two digits of CL are displayed as exponent, and the upper bits in CL control minus-signs and a decimal point after the first digit. Javascript-online-assembler-and-simulatorI have made an assembler and simulator in Javascript, (I modified the assembler-simulator from Marco Schweighauser). The simulator includes a calculator display and keys. You can download it from the file list, or try it online at: www.enscope.nl/rrca The first program is a 8-digit calculator that can only add. You can paste the following code in the online assembler, assemble it and start the simulator. ; CPU simulator test. ; Only calculates: A + B = NOP ;first instruction is skipped ! clr: plus: LDL Y,X ; save X in Y (32 bit) SUBL X,X ; clr X (32 bit) waitkey: HLT ; wait for button press ; HLT ; option for switching to single step TEQ CL,'+' BRZ plus TEQ CL,'=' BRZ result TEQ CL,' ' ; CLR pressed ? BRZ clr ADD CL,0xffd0 ; keep digit code (subtr 0x30) ADDL X,X ; shift X one digit left ADDL X,X ADDL X,X ADDL X,X ADD XL,CL ; add new digit at the right side BR waitkey NOP ; delay slot: the instruction after BR is also executed ! result: DADDL X,Y ; 32-bit decimal add (Decimal ADD Long) BR waitkey
After a calculation, press the "clr" button before a new calculation is started. Change the code and build your own calculator online ! You can also use scientific notation: two digits of CL are displayed as exponent, and the upper bits in CL control minus-signs and a decimal point after the first digit.
|