Close

Operations: +, - (also BCD addition)

A project log for Bit-serial CPU based on crossbar switch

256 switches and few shift registers to implement a working 16 or 32-bit integer arithmetic calculator (+, -, *, /, isqrt, BCD / bin conv..)

zpekiczpekic 05/01/2022 at 03:440 Comments

(Refer to microcode for description)

Adding and substracting is done in a typical 2's complement fashion: 

+ (TOS <= TOS + NOS, pop stack)

Microcode trace, 16-bit, tracing of instruction enabled ("ti") of result disabled ("tr"). Fields are:

+ 00 05 echo(input);         then emit e                     +
+ 00 FC emit: if TXDSEND then else repea                     +
+ 00 FE if TXDREADY then nextr_zero, if                      +
+ 00 06 if true then fork els STATUS = b                     .
+ 00 DC matrix_pop: STATUS = t, MT_CTRL                      .
+ 00 DE STATUS = busy_using_mt, MT_CTRL                      .
+ 00 E0 STATUS = busy_using_mt, MT_CTRL                      .
+ 00 3B add: STATUS = busy_usng_mt, MT_C                     .
+ 00 3D STATUS = busy_using_m                                .
+ 0F CA div2: STATUS = busy_use then nex                     .
+ 0E CA div2: STATUS = busy_use then nex                     .
+ 0D CA div2: STATUS = busy_use then nex                     .
+ 0C CA div2: STATUS = busy_use then nex                     .
+ 0B CA div2: STATUS = busy_use then nex                     .
+ 0A CA div2: STATUS = busy_use then nex                     .
+ 09 CA div2: STATUS = busy_use then nex                     .
+ 08 CA div2: STATUS = busy_use then nex                     .
+ 07 CA div2: STATUS = busy_use then nex                     .
+ 06 CA div2: STATUS = busy_use then nex                     .
+ 05 CA div2: STATUS = busy_use then nex                     .
+ 04 CA div2: STATUS = busy_use then nex                     .
+ 03 CA div2: STATUS = busy_use then nex                     .
+ 02 CA div2: STATUS = busy_use then nex                     .
+ 01 CA div2: STATUS = busy_use then nex                     .
+ 00 CA div2: STATUS = busy_u                                .
+ 00 F3 print_st: loopcnt <= se nextchar                     .
. 00 11 nextchar: STATUS = do
 

The matrix is simple, TOS and NOS are inputs to adder, and sum (adder output row) is fed into TOS. All other registers are "popped" (Rx <= Rx-1, R7 <= 0)

The resulting carry is correct, and implementing overflow status bit would be simple too (V = Cn xor Cn-1), but it is not done in this design.

- (TOS <= TOS - NOS, pop stack)

TOS is connected to one input of adder, but NOS goes through inverter. Implementing NOS - TOS would just to re-wire TOS to go through the inverter.

Tracing 16-bit subtraction with "tr" (trace result) enabled - this prints out 4 hex characters for the value of TOS. Loopcnt register is used for this, while bitcnt remains 0.

- 00 05 echo(input);         then emit e                     -
- 00 FF emit0: TXDCHAR <= chae fork;                         .
- 00 3E minus: c_flag <= one,busy_using_                     .
- 00 DD STATUS = busy_using_mt, MT_CTRL                      .
- 00 DF STATUS = busy_using_mt, MT_CTRL                      .
- 00 E1 STATUS = busy_using_mt, MT_CTRL                      .
- 00 40 STATUS = busy_using_mng_mt, MT_C                     .
- 00 3D STATUS = busy_using_m                                .
- 0F CA div2: STATUS = busy_use then nex                     .
- 0E CA div2: STATUS = busy_use then nex                     .
- 0D CA div2: STATUS = busy_use then nex                     .
- 0C CA div2: STATUS = busy_use then nex                     .
- 0B CA div2: STATUS = busy_use then nex                     .
- 0A CA div2: STATUS = busy_use then nex                     .
- 09 CA div2: STATUS = busy_use then nex                     .
- 08 CA div2: STATUS = busy_use then nex                     .
- 07 CA div2: STATUS = busy_use then nex                     .
- 06 CA div2: STATUS = busy_use then nex                     .
- 05 CA div2: STATUS = busy_use then nex                     .
- 04 CA div2: STATUS = busy_use then nex                     .
- 03 CA div2: STATUS = busy_use then nex                     .
- 02 CA div2: STATUS = busy_use then nex                     .
- 01 CA div2: STATUS = busy_use then nex                     .
- 00 CA div2: STATUS = busy_u                                .
- 00 F3 print_st: loopcnt <= _crlf();                        .
- 00 FA print_crlf: emit(char next else                      .
- 00 FD if TXDREADY then next else repea                     .
- 00 FF emit0: TXDCHAR <= cha                                .
- 00 FC emit: if TXDSEND then else repea                     .
- 00 FE if TXDREADY then nextr_zero, if                      .
- 00 F5 st_loop: selreg = int next else                      F
- 00 FD if TXDREADY then next else repea                     F
- 00 FF emit0: TXDCHAR <= chainc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theen print_cr                     .
- 00 F5 st_loop: selreg = int next else                      B
- 00 FD if TXDREADY then next else repea                     B
- 00 FF emit0: TXDCHAR <= chainc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theen print_cr                     .
- 00 F5 st_loop: selreg = int next else                      B
- 00 FD if TXDREADY then next else repea                     B
- 00 FF emit0: TXDCHAR <= chainc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theen print_cr                     .
- 00 F5 st_loop: selreg = int next else                      A
- 00 FD if TXDREADY then next else repea                     A
- 00 FF emit0: TXDCHAR <= chainc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theinc;                            .
- 00 F7 if loopcnt_nibble theen print_cr                     .
- 00 FA print_crlf: emit(char next else                      .
- 00 FD if TXDREADY then next else repea                     .
- 00 FF emit0: TXDCHAR <= cha                                .
- 00 FC emit: if TXDSEND then else repea                     .
- 00 FE if TXDREADY then nextr_zero, if                      .
- 00 39 if false then next elne, if fals                     .

(there is a but, loopcnt is actually not displayed correctly in the trace above, will be fixed) 

BCD addition

TO BE CONTINUED...

Discussions