|
|
I'm working through making the ALU.
To be honest, I got through the first few steps and then "cheated" by looking on Google Code.
I am working through it to make sure I really get it, and I think I do until the last bit, determining the value of zr.
I get how the six input bits affect a and b to create out.
I get that:
If out[15] = 0 --> ng=0 else ng=1.
What I can't figure out is how the determination is made that "out" is either equal to zero or not based exclusively on messing with out[15]. Obviously, if out[15] = 1, the number can't be zero, since that 1 indicates a non-zero negative number.
Can anyone explain the logic, please?
|
Administrator
|
mbm29414 wrote
What I can't figure out is how the determination is made that "out" is either equal to zero or not based exclusively on messing with out[15]. Obviously, if out[15] = 1, the number can't be zero, since that 1 indicates a non-zero negative number.
'zr' cannot be determined based solely on out[15]. You must determine that out[0..15] are all 0. Or, conversely, you must determine that out[0..15] are not all 0 to determine 'not zr'. One of the chips you made in project 1 gets you halfway there...
--Mark
|
|
That's what I thought, but the code in the file from Google Code seemed to indicate you could.
Here's the Google Code section:
-----------------------------------------------------
/** out2 is the same as the value passed to out
* ng1 is the same as the value passed to ng
*/
Add16(a[0..15]=out2, b[0..15]=true, out[0..15]=out3, out[15]=out315);
Not(in=ng1, out=ngcomp);
And(a=ngcomp, b=out315, out=zr);
So, in the code above, the output value is added to '1111111111111111'. Then, the result is stored into a 16-bit bus and the left-most digit is stored into a 1-bit bus. (Side question: As far as I can tell, out3 is never used; is it only "produced" because you have to have a "full" out before grabbing part of it? Could you not just leave out the "out[0..15]=out3" part?) Then, ng1 (the left-most digit of the output value) is negated and zr is set to ngcomp*out315. This doesn't make sense to me, but I was thinking that these posts are from the authors.
The thought I've had was something like this:
-----------------------------------------------------
Add16(a=outValue, b[0..15]=true, out=allOnesTest);
And16Way(in=allOnesTest, out=zr);
Of course, we never made an And16Way chip, but I'm thinking along those lines because the first line (or something like it) was in the Google Code file.
If I were to do it from scratch (using the hint you gave), I'd probably come up with this:
-----------------------------------------------------
Or8Way(in=outValue[0..7], out=firstPartOr);
Or8Way(in=outValue[8..15], out=secondPartOr);
Or(a=firstPartOr, b=secondPartOr, out=orOut);
Not(in=orOut, out=zr);
Is there a better/more efficient way to do this? Am I at least on the right track?
|
Administrator
|
mbm29414 wrote
That's what I thought, but the code in the file from Google Code seemed to indicate you could.
Here's the Google Code section:
-----------------------------------------------------
/** out2 is the same as the value passed to out
* ng1 is the same as the value passed to ng
*/
Add16(a[0..15]=out2, b[0..15]=true, out[0..15]=out3, out[15]=out315);
Not(in=ng1, out=ngcomp);
And(a=ngcomp, b=out315, out=zr);
So, in the code above, the output value is added to '1111111111111111'. Then, the result is stored into a 16-bit bus and the left-most digit is stored into a 1-bit bus. (Side question: As far as I can tell, out3 is never used; is it only "produced" because you have to have a "full" out before grabbing part of it? Could you not just leave out the "out[0..15]=out3" part?) Then, ng1 (the left-most digit of the output value) is negated and zr is set to ngcomp*out315. This doesn't make sense to me, but I was thinking that these posts are from the authors.
The above circuit does work, but is extremely inefficient; Add16 is huge and slow! Here's what the circuit does:
out2 = out (given)
ng1 = ng (given)
= (out < 0)
out315 = (out-1 < 0)
= (out < 1)
ngcomp = ! ng1
= (out >= 0)
zr = (out >= 0) & (out < 1)
= (out = 0)
As you noticed, 'out3' is unused and is not required.
Your final solution is an efficient solution. Other than signal names it's the same as mine.
--Mark
|
|
Yeah, the signal names were only for clarity in the post; I'd shorten them for the real code.
Thanks for the help. I knew I wasn't crazy!
As I learned from Aaron Hillegass:
"This is hard. I'm not stupid."
:)
|
|
The problem is that the solution described below does not work:
Or8Way(in=outValue[0..7], out=firstPartOr);
Or8Way(in=outValue[8..15], out=secondPartOr);
Or(a=firstPartOr, b=secondPartOr, out=orOut);
Not(in=orOut, out=zr);
I keep getting a sub-bussing error.
Sub bus of an internal node may not be used.
|
Administrator
|
Eric M wrote
The problem is that the solution described below does not work:
Or8Way(in=outValue[0..7], out=firstPartOr);
Or8Way(in=outValue[8..15], out=secondPartOr);
Or(a=firstPartOr, b=secondPartOr, out=orOut);
Not(in=orOut, out=zr);
I keep getting a sub-bussing error.
Sub bus of an internal node may not be used.
You must create the 8-bit buses from a chip output:
Something16(... out[0..7]=lowBits, out[8..15]=highBits, ...);
Study the example in A.5.3.
--Mark
|
|