Channels ▼

Al Williams

Dr. Dobb's Bloggers

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

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):

	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;

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.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips 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.