Klaus:
Thanks for your pointer. Did not kick-off the binary mode test on the computer last night. But I will study your suggestions in the event I need to perform the tests in several passes.
I also like to perform exhaustive tests. The decimal mode arithmetic test for the BCD adder module of the core is exhaustive like your functional tests. I have opted to use your functional tests, although I recognize they were written for an emulator instead of a chip, because it provides a common basis for comparison among the various simulators, emulators, and cores. Ideally, the FPGA cores should have test benches that should determine if the various components meet their objectives.
In the case of the M65C02, I have such a test bench for every major module, and some not so major, including the BCD adder logic. The issue that your functional tests discovered was not associated with a fault in the logic of the M65C02_BCD.v module. Instead, when I recently changed the bus implementation in the ALU and core, it became possible that the results of one module, unless driven to logic 0, would corrupt the data from another component.
With multiplexer-based buses, the additional combinatorial delays were limiting the ability of the core to operate at a high rate. I failed to account for the extra cycle that the registered Decimal Unit (DU) enable FF (rEn) would remain set after its results were pulled off the ALU output bus and into A and P. Thus, it remained asserted beyond its allocated time on the ALU bus, and its LSB was set, i.e. A = $99 and P = $2C, so when P was pushed onto the stack, a value of $BD was written instead of $3C.
My regression test program is not sophisticated enough to identify this issue. It may be possible to expand it to address these types of issue, and I'll give that some thought. However, my inclination is to modify the HDL testbenches to perform this level of testing.
Your exhaustive testing approach may be time consuming and difficult to implement in an FPGA simulation environment because of its long runtimes, but it provides significant benefits that more limited targeted tests will not. To find timing faults like the one I found in my core with your functional tests simply requires test cycles. The fewer cycles of a targeted test is less likely to generate the conditions necessary to find bus overlaps.
The results reported by me, you, and others simply reinforce the need for exhaustive testing, and your functional tests provide a common set of tests that can be used in simulators, emulators, and FPGA cores. That versatility in invaluable and a testament to the quality of the tests.
Klaus2m5 wrote:
You should always keep in mind, that the test was originally written for an emulator. For the non-exhaustive tests the predefined operands are choosen according to the need to test all possible combinations of resulting processor status bits.
Since logical operations in an emulator rely on the logical operations of the underlying processor, the test does not guarantee the logical functionality of each and every bit in the alu. It assumes the underlying logical operation to be correct if a limited number of patterns come out of the alu with a correct result.
In that sense it leaves a gap where a broken function in a single bit of an fpga core alu may go undetected. I don't know, how likely this is to happen but it is an exposure that you should be aware of.
The nature of the HDL process fits in with the nature of the tests that you have built for the logic, shift, and rotate functions. Like the emulator, the logic used to implement the AND, EOR, ORA, ASL, LSR, ROL, and ROR instructions is a fundamental component of the HDL. There's no need to check that these functions have been correctly implemented for each bit. That being said, an implementation issue as I found with overlapping bus enables, could be more readily discovered with exhaustive tests of these functions.
However, to test for that type of timing issue requires intimate knowledge of the internal structure of the HDL design. Further, if the M65C02 was not pipelined and memory cycle optimized, then the overlap on the internal bus would not have been an issue at all. The overlap between the decimal adder unit and P on the ALU output bus occurred because there are no dead cycles in the M65C02's implementation. In a more standard implementation, the PHP instruction fetch cycle would have provided enough of a delay to allow the decimal adder unit registered output enable to be deasserted before P is required on the output bus to complete the PHP instruction.
Now that I've found this issue, I will try and determine a test sequence that can be used with the M65C02 core and soft-processor for regression testing of this fault. Another time where this overlap can be an issue is between the completion of an instruction and the initiation of the push of {PCH, PCL} or {PCH, PCL, P} onto the stack. If there is an overlap between the various data sources on the output bus, ALU output bus, dPCH, dPCL, and P, then there's a potential for the same kind of corruption of the value pushed onto the stack as occurred with your decimal mode ADC/SBC test. (
Note: the binary mode adder is fully combinatorial, so there's no potential for the kind bus overlap that can occur with the decimal mode adder except as a design flaw in the FPGA mapper/router. The decimal mode adder has a fully combinatorial first stage and that is followed by decimal adjustment logic that is fed from the registered results of the combinatorial first stage.)