Skip to content

Commit

Permalink
- The div instruction gave wrong results in some corner cases when ei…
Browse files Browse the repository at this point in the history
…ther

  divisor or quotient were the largest negative integer (100000 or -32768).
  This is corrected now, for details see ECO-026-div.txt
- some minor updates and fixes to support scripts
- xtwi usage and XTWI_PATH setup explained in INSTALL.txt
  • Loading branch information
wfjm committed Aug 10, 2014
1 parent 46331ca commit 093d540
Show file tree
Hide file tree
Showing 91 changed files with 2,174 additions and 1,018 deletions.
1 change: 1 addition & 0 deletions .cvsignore
Expand Up @@ -25,6 +25,7 @@ fuse.log
*_twr.log
*_map.log
*_par.log
*_tsi.log
*_pad.log
*_bgn.log
*_svn.log
Expand Down
3 changes: 2 additions & 1 deletion Makefile
@@ -1,11 +1,12 @@
# $Id: Makefile 538 2013-10-06 17:21:25Z mueller $
# $Id: Makefile 562 2014-06-15 17:23:18Z mueller $
#
# 'Meta Makefile' for whole retro project
# allows to make all synthesis targets
# allows to make all test bench targets
#
# Revision History:
# Date Rev Version Comment
# 2014-06-14 562 1.0.8 suspend nexys4 syn targets
# 2013-09-28 535 1.0.7 add nexys4 port for sys_gen/tst_sram,w11a
# 2013-05-01 513 1.0.6 add clean_sim_tmp and clean_syn_tmp targets
# 2012-12-29 466 1.0.5 add tst_rlink_cuff
Expand Down
108 changes: 108 additions & 0 deletions doc/ECO-026-div.txt
@@ -0,0 +1,108 @@
$Id: ECO-026-div.txt 579 2014-08-08 20:39:46Z mueller $

Scope:
Introduced in release w11a_V0.61
Affects: all w11a systems

Symptom summary:
The div instruction gave wrong results in some corner cases when either
divisor or quotient were the largest negative integer (100000 or -32768):
1. wrong q and r when dd=n*(-32768), dr=-32768 with n even
2. V=1 set when division solvable and proper result is q=-32768

Background:
The PDP-11/70 (KB11-C) and the w11a use very different division algorithms.
Both use a non-restoring divide.
- The KB11-C uses a straight forward 2 quadrant core algorithm for positive
dividends and positive or negative divisors. Negative dividends are first
converted to positive, the results later corrected. This leads to quite
complex implementation with 35 micro states.
- The w11a uses a 4 quadrant algorithm which directly allows positive and
negative dividends and divisors. The qbit logic is much more complex in
this case. Advantage is that the whole divide algorithm can be implemented
with only 6 states in the main sequencer.

In twos complement integer arithmetic, as used in the pdp11 and almost all
contemporary computers, the range of positive and negative numbers is
different, for 16 bit for example
oct 100000 to 077777
dec -32768 to +32767
so the smallest negative number has no positive counterpart. Trying to negate
the smallest negative number leads to the same number
mov #100000, r0
neg r0 --> r0 = 100000; V=1

These special properties of the largest negative number easily lead to corner
cases which require special treatment, both the KB11-C and the w11a divide
algorithms need special rules and checks for this.

Summary of issues:
1. when dividend was dd=n*(-32768) with an even n and the divisor was
dr=-32768 the old w11a algorithm returned wrong quotient and remainder
values and V=0 status.
2. for all divisions which result in a quotient of -32768 the old w11a
algorithm set the overflow (V=1) condition. Since in this case the
destination registers were not updated and still contained the
dividend, software not checking the V code saw wrong quotient and
remainder values.

Fixes:
- Issue 1: wrong q and r for dd=n*(-32768), dr=-32768 with n even.
- the corner case is detected in state s_opg_div by testing that divisor
is 0100000 and low order part of dividend is zero. When detected, the
qbit logic is modified and quotient and remainder corrections are done
unconditionally.

- Issue 2: V=1 set when division solvable and proper result is q=-32768.
The divide core algorithm calculates the correct q and r, only the
overflow testing was incorrect.
The old algorithm had two overflow abort conditions
- a check that bit 31 and 30 of the dividend are equal
- a check after the first division cycle
The new algorithm now has three overflow abort conditions
- the bit 31/30 check on the dividend was too restrictive. Valid divisions
with dd=(-32768)*(-32768)+n and dr=-32768 giving q=-32768 and r=n would
be rejected. The 31/30 check is now only applied when the divisor is not
equal 0100000
- the division abort condition in the first division cycle was completely
revised, this avoids that solvable divisions are aborted at this stage
- the first two conditions don't catch all overflow situations. The
remaining ones all have after the quotient correction stage q>0 when
a negative quotient is expected. A third overflow check was added to
s_opg_div_sr to handle these cases.

Side effects:
- the old implementation guaranteed that the destination registers were
unchanged in case of overflow. The new does not, the overflow check in
s_opg_div_sr is done after the quotient is stored, and storing remainder
is not suppressed in case of overflow. So both q and r regs are changed.
- with additional states it could be guaranteed that destination registers
are never updated in case of overflow. See proviso below.
- the pdp-11/70 KB11-C in most cases keeps destination registers unchanged
in case of overflow, but also has a late check after one register has
been modified.
- the J11 never updates registers in case of overflow. A case like
0,177777 / 177777 were w11a now updates regs is known from J11
diagnostics to not update in J11.
- simh always preserves the destination registers in case of overflow.

!! the pdp11 processor handbook considers the destination registers as !!
!! undefined in case of division overflow, so the w11a behavior is OK. !!

Provisos:
- the behavior after V=1 aborts of a div instruction is now different in
- w11a --> regs updated under some rare conditions
- KB11-C --> regs updated under some rare conditions
but in cases different from w11a
- 11/44 --> regs updated under some conditions (see v7_longdivide_bug.txt)
- J11 --> regs never updated
- simh --> regs never updated
--> that can lead to spurious failures in original DEC diagnostics when
they test the complete response
--> even though the current w11a behavious is full within specs it is unclear
whether all software tolerates this, especially non-DEC OS. Unix V7 is
known to have an issue with ldiv and CPUs not preserving regs, see
http://minnie.tuhs.org/PUPS/v7_longdivide_bug.txt
--> Only further studes can show whether it is worth the effort and the
slow down of 1-2 cycles to guarantee preserved registers.

63 changes: 63 additions & 0 deletions doc/FILES.txt
@@ -0,0 +1,63 @@
$Id: FILES.txt 577 2014-08-03 20:49:42Z mueller $

Short description of the directory layout, what is where ?

doc Documentation
doc/man man pages for retro11 commands
rtl VHDL sources
rtl/bplib - board and component support libs
rtl/bplib/atlys - for Digilent Atlys board
rtl/bplib/fx2lib - for Cypress FX2 USB interface controller
rtl/bplib/issi - for ISSI parts
rtl/bplib/micron - for Micron parts
rtl/bplib/nexys2 - for Digilent Nexsy2 board
rtl/bplib/nexys3 - for Digilent Nexsy3 board
rtl/bplib/nxcramlib - for CRAM part used in Nexys2/3
rtl/bplib/s3board - for Digilent S3BOARD
rtl/ibus - ibus devices (UNIBUS peripherals)
rtl/sys_gen - top level designs
rtl/sys_gen/tst_fx2loop - top level designs for Cypress FX2 tester
nexys2,nexys3 - systems for Nexsy2,Nexsy3
rtl/sys_gen/tst_rlink - top level designs for an rlink tester
nexys2,nexys3,s3board - systems for Nexsy2,Nexsy3,S3BOARD
rtl/sys_gen/tst_rlink_cuff - top level designs for rlink over FX2 tester
nexys2,nexys3,atlys - systems for Atlys,Nexsy2,Nexsy3
rtl/sys_gen/tst_serloop - top level designs for serport loop tester
nexys2,nexys3,s3board - systems for Nexsy2,Nexsy3,S3BOARD
rtl/sys_gen/tst_snhumanio - top level designs for human I/O tester
atlys,nexys2,nexys3,s3board - systems for Atlys,Nexsy2,Nexsy3,S3BOARD
rtl/sys_gen/w11a - top level designs for w11a SoC
nexys2,nexys3,s3board - w11a systems for Nexsy2,Nexsy3,S3BOARD
rtl/vlib - VHDL component libs
rtl/vlib/comlib - communication
rtl/vlib/genlib - general
rtl/vlib/memlib - memory
rtl/vlib/rbus - rri: rbus
rtl/vlib/rlink - rri: rlink
rtl/vlib/serport - serial port (UART)
rtl/vlib/simlib - simulation helper lib
rtl/vlib/xlib - Xilinx specific components
rtl/w11a - w11a core
tools helper programs
tools/asm-11 - pdp-11 assembler code
tools/asm-11/tests - test bench for asm-11
tools/asm-11/tests-err - test bench for asm-11 (error check part)
tools/bin - scripts and binaries
tools/dox - Doxygen documentation configuration
tools/make - make includes
tools/fx2 - Firmware for Cypress FX2 USB Interface
tools/fx2/bin - pre-build firmware images in .ihx format
tools/fx2/src - C and asm sources
tools/fx2/sys - udev rules for USB on fpga eval boards
tools/oskit - setup files for Operation System kits
tools/oskit/... - several PDP-11 system kits available
tools/src - C++ sources for rlink backend software
tools/src/librlink - basic rlink interface
tools/src/librlinktpp - C++ to tcl binding for rlink interface
tools/src/librtcltools - support classes to implement Tcl bindings
tools/src/librtools - general support classes and methods
tools/src/librutiltpp - Tcl support commands implemented in C++
tools/src/librw11 - w11 over rlink interface
tools/src/librwxxtpp - C++ to tcl binding for w11 over rlink iface
tools/tbench - w11 CPU test bench
tools/tcl - Tcl scripts

0 comments on commit 093d540

Please sign in to comment.