# Expanding VTACH

May 20, 2013

You can download updated vtach files. The updates lengthen the accumulator, fix a few bugs (including the one fixed last time), and add the TAC and SFT instructions. If you want to look at what a mess decimal math makes, look at bcdadd.v and digitadd.v. Here's an excerpt from bcdadd.v:

```assign signtemp={ 1'b0, c4} + {1'b0, a[16]} + { 1'b0, b[12]};
assign asign=a[16];
assign bsign=b[12];
assign a0=asign?9-a[3:0]:a[3:0];
assign b0=bsign?9-b[3:0]:b[3:0];
assign a1=asign?9-a[7:4]:a[7:4];
. . .
assign sumsign=signtemp[0];

digitadd add1(a0,b0,asign|bsign,r,c1);  // add 1 when adding any negative number
digitadd add2(a1,b1,c1,q,c2);
digitadd add3( a2, b2,c2,p,c3);
digitadd add4(a3, b3,c3, p0,c4);
assign tempneg={ 1'b1, 4'h9-p0, 4'h9-p, 4'h9-q, 4'h9-r};
assign z=sumsign?((tempneg==17'h10000)?17'h10001:tempneg):{ 1'b0,p0, p,q,r};
```

The `digitadd` components do most of the work, although each digit is converted (partially) to 9's compliment if negative (the 9 subtractions occur when `a0`, `b0`, and the similar wires are populated; the adding of the one is not done until later).

The digitadd.v file is fairly straightforward:

```// add everything together in binary
assign temp={1'b0,a}+{1'b0,b}+{4'b0, cyin};

// Now look at the answer and decode
always @(a,b,cyin) begin
case (temp)
10: begin z=4'h0; cyout=1'b1; end
11: begin z=4'h1; cyout=1'b1; end
12: begin z=4'h2; cyout=1'b1; end
13: begin z=4'h3; cyout=1'b1; end
14: begin z=4'h4; cyout=1'b1; end
15: begin z=4'h5; cyout=1'b1; end
16: begin z=4'h6; cyout=1'b1; end
17: begin z=4'h7; cyout=1'b1; end
18: begin z=4'h8; cyout=1'b1; end
19: begin z=4'h9; cyout=1'b1; end
// all other cases are easy
default: begin z=temp[3:0];  cyout=1'b0; end
endcase
```

Remember, this just adds a single digit. The largest possible sum is 9+9+1 (the carry from the last digit), so anything over 19 should never happen. Any result from 10 to 19 requires special processing. Everything else just passes through. The bcdadd.v file assembles all the results (and converts back from 9's compliment if required).

This was confusing enough that it was worth writing a test bench just to test all the corner cases (bcdadd_tb.v):

```   initial
begin
\$dumpfile("bcdadd.vcd");
\$dumpvars;
a=0;
b=1;   // z=1
#10 a=1;
b=13'h1001;   // z=0
#10 a=2;      // z=1
#10 a=17'h10001;  // z=-2
#10 b=13'h1002;  // z=-3
#10 a=0;
#10 \$finish;
end
```

This just sets up a few test cases. You could print the results out, if you prefer, by adding something like:

```#1 \$display("Result=%h\n",z);
```

The #1 gives the logic time to process the last settings and the `\$display` works much like `printf` in C (you can use %x or %h for hex format). I didn't print the results, but just dumped them to a VCD file like I did last time. Here's the resulting output:

Below is a simple program that uses the new TAC instruction. Location 20 and 21 store constants used by the program (10 and 1, respectively). The program initializes a loop counter variable (at location 22) from location 20, so the count starts at 10. The main loop starts on the instruction that stores the accumulator to the loop variable (location 1). The loop outputs the counts, subtracts the 1 (from location 21), and jumps to location 10 if the result is negative. If the result isn't negative, the program jumps back to the top of the loop.

```     dut.mem.row0[0]=13'h120;  // load location 20 (10)
dut.mem.row0[1]=13'h622;  // Store to location 22
dut.mem.row0[2]=13'h522;  // output location 22
dut.mem.row0[3]=13'h721;  // subtract [21] (1)
dut.mem.row0[4]=13'h310;  // if negative goto 10
dut.mem.row0[5]=13'h801;  // goto 1
dut.mem.row1[0]=13'h900;  // halt
dut.mem.row2[0]=13'h010;  // constant 10
dut.mem.row2[1]=13'h001;  // constant 1
dut.mem.row2[2]=13'h000;  // workspace
```

That pretty much wraps up simulation of vtach, assuming I caught all the bugs. The next step would be to make program loading easier and plan how to put the thing on an actual FPGA.

### More Insights

 To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.