Monday, March 21, 2011

Remembering classic logic... (part 7)

Recently I pulled out my boxes of 7400 series logic (working on a few old school projects that were idled for a bit).  There's something special about these chips...

So, on a whim I thought that I'd bang out verilog modules for the chips I have on hand.  I'm putting the files for these modules in the tanukifu project here.


There are times when one has a number of separate lines (usually connected to similar outputs of different chips) and a single input needs to be connected to exactly one of these outputs... A mux (multiplexer) uses a small number of address lines to determine which of the inputs should be connected to the outputs.  The 74x151 allows 3 address lines to select from 1 of 8 inputs and to present that line as well as it's compliment as outputs.


The hdl is easy here...


// if the strobe is low then set the outputs to the input based on
   // the select lines, otherwise Aout is low and Ainv is high.
   assign Aout = (strobe) ? 1'b0 :  Aint;
   assign Ainv = ~Aout;

   assign select = {Asel, Bsel, Csel};
  
   always @ (*) begin
      case (select)
        (3'b000) : Aint = A1;
        (3'b001) : Aint = A2;
        (3'b010) : Aint = A3;
        (3'b011) : Aint = A4;
        (3'b100) : Aint = A5;
        (3'b101) : Aint = A6;
        (3'b110) : Aint = A7;
        (3'b111) : Aint = A8;
      endcase
   end
The 74x451 effectively combines two 8 to 1 muxes and makes the outputs tristates. 

// if the strobe is low then set the outputs to the input based on
   // the select lines, otherwise Aout is low.
   assign Aout = (strobe) ? 1'b0 :  Aint;
   assign Bout = (strobe) ? 1'b0 :  Bint;

   assign select = {Asel, Bsel, Csel};
  
   always @ (*) begin
      case (select)
        (3'b000) : Aint = A1;
        (3'b001) : Aint = A2;
        (3'b010) : Aint = A3;
        (3'b011) : Aint = A4;
        (3'b100) : Aint = A5;
        (3'b101) : Aint = A6;
        (3'b110) : Aint = A7;
        (3'b111) : Aint = A8;
      endcase
   end // always @ (*)
  
   always @ (*) begin
      case (select)
        (3'b000) : Bint = B1;
        (3'b001) : Bint = B2;
        (3'b010) : Bint = B3;
        (3'b011) : Bint = B4;
        (3'b100) : Bint = B5;
        (3'b101) : Bint = B6;
        (3'b110) : Bint = B7;
        (3'b111) : Bint = B8;
      endcase
   end
The 74x251 is a single 8 to 1 mux with tristates but includes complimentary outputs.  This is particularly useful when muxes are used to build math functions.

// if the strobe is low then set the outputs to the input based on
   // the select lines, otherwise Aout is low and Ainv is high.
   assign Aout = (enable) ? 1'bz :  Aint;
   assign Ainv = (enable) ? 1'bz : ~Aint;

   assign select = {Asel, Bsel, Csel};
  
   always @ (*) begin
      case (select)
        (3'b000) : Aint = A1;
        (3'b001) : Aint = A2;
        (3'b010) : Aint = A3;
        (3'b011) : Aint = A4;
        (3'b100) : Aint = A5;
        (3'b101) : Aint = A6;
        (3'b110) : Aint = A7;
        (3'b111) : Aint = A8;
      endcase
   end
The last one I like to use is the 74x353 which contains two separate 4 to 1 muxes with the same address lines (but here the outputs are inverted).  It's a lot more common for me to need 2 smaller muxes in a design than 1 larger one.
  assign Aout = (enable) ? 1'bz : ~Aint;
   assign Bout = (enable) ? 1'bz : ~Bint;

   assign select = {Asel, Bsel};
  
   always @ (*) begin
      case (select)
        (2'b00) : Aint = A1;
        (2'b01) : Aint = A2;
        (2'b10) : Aint = A3;
        (2'b11) : Aint = A4;
      endcase
   end
  
   always @ (*) begin
      case (select)
        (2'b00) : Bint = B1;
        (2'b01) : Bint = B2;
        (2'b10) : Bint = B3;
        (2'b11) : Bint = B4;
      endcase
   end        
Most of the time I used muxes for scanning low speed (not time sensitive) inputs for a state change, or selecting which of several similar devices to pay attention to (if I can't connect them to a common bus).  Sometimes I used them in feedback configurations to make more complicated logic.  There are some very interesting things they can do when mixed with ram and a few other logic chips that form the basics of a processor.   One can also use these chips to connect active pipes (higher speed serial connections) from multiple devices to drive an even faster connection efficiently.

I tended to find demuxes (de-multiplexers) more useful (those we cove next time).