hdlnand2tetris

sel[1] and sel[2] have different bus widths error when trying to build and 8 way demux using the nand2tetris HDL


I do not understand why the former implementation works but the latter does not. I can understand the logic behind both of them, and in my mind they are esentially the same, just with the former using sel[0..1] as a short hand instead of having to use extra demux gates with sel[0] and sel[1].

CHIP DMux8Way {
    IN in, sel[3];
    OUT a, b, c, d, e, f, g, h;

    PARTS:
    // Working code
    // DMux(in=in, sel=sel[2], a=outA, b=outB);
    // DMux4Way(in=outA, sel=sel[0..1], a=a, b=b, c=c, d=d);
    // DMux4Way(in=outB, sel=sel[0..1], a=e, b=f, c=g, d=h);

    // Non working code; produces error "Sel (1) and sel (2) have different bus widths"
    DMux(in=in, sel=sel[2], a=outA, b=outB);
    DMux(in=outA, sel=sel[1], a=outA1, b=null);
    DMux(in=outB, sel=sel[1], a=null, b=outB1);
    DMux4Way(in=outA1, sel=sel[0], a=a, b=b, c=c, d=d);
    DMux4Way(in=outB1, sel=sel[0], a=e, b=f, c=g, d=h);
} 

I do not see how I am causing the error "Sel (1) and sel (2) have different bus widths". If sel === 001 then surely sel[1] would be 0 and sel[2] would be 1 in which case both indexes are 1 bit and therefore the same width. I know that the latter implementation is inefficent but I just want to know why this is happening to ensure I fully understand it. (the reason for me assigning null to b in the second demux gate and vice versa for the third demux gate is to prevent the error "an internal pin may only be fed once by a parts output pin", originally I had one demux gate and then used both internal pints to feed the 4 way demux gates). If this isn't the case with how indexing works in the nand2tetris HDL then how does my 4 way mux gate work?

CHIP Mux4Way16 {
    IN a[16], b[16], c[16], d[16], sel[2];
    OUT out[16];
    
    PARTS:
    Mux16(a=a, b=b, sel=sel[0], out=out1);
    Mux16(a=c, b=d, sel=sel[0], out=out2);
    Mux16(a=out1, b=out2, sel=sel[1], out=out);
}

The only thing I can think of (which doesn't make any sense to me and seems ridiculous) is that in a scenario, for example where the value of sel is 001, sel[2] would be 001, sel[1] would be 00 and sel[0] would be 0.

I have asked this question on the nand2tetris form and am currently awaiting a reply, but it can take a while before getting a reply so I thought it would be a good idea to ask on here as well.


Solution

  • They are NOT the same.

    A DMux4Way requires 2 bits of sel input to select which of the 4 outputs becomes true. In your non-working example, you are only providing 1 bit (sel[0]) thus the error.

    In order to do what you want without using DMux4Way (ie: using DMux only) you would need a 1-2-4 cascade of DMux's, the first handling sel[2], the second two handling sel[1] and the final four handling sel[0].

    Finally, if for some reason you don't need a particular output pin, just don't define it; no need to use null (heck, I didn't even know you could, and I've been messing around with NAND2Tetris for almost a decade!)