4-to-16 line decoder

Hey! He asked you not to spoil it for him! >:-(

Thanks, Rich

Reply to
Rich Grise
Loading thread data ...

Split it in two right down the middle, and condense the left half into just the four states, and notice how those associate with the other 16 states, which are the same pattern of four, repeated four times again. :-)

Cheers! Rich

Reply to
Rich Grise

It sounds as though you are getting it. Here's one more description to see if it makes any difference.

You need:

: ,-------------------------------, : | | : ENA >-----| |--> O 00 : | |--> O 01 : | |--> O 02 : | |--> O 03 : | | : | | : | |--> O 04 : | |--> O 05 : | |--> O 06 : | |--> O 07 : | | : | | : | |--> O 08 : | |--> O 09 : | |--> O 10 : I 00 >-----| |--> O 11 : | | : I 01 >-----| | : | |--> O 12 : I 02 >-----| |--> O 13 : | |--> O 14 : I 03 >-----| |--> O 15 : | | : '-------------------------------'

And must use some number of these:

: ,--------, : ENA >-----| |--> O 00 : | |--> O 01 : I 00 >-----| |--> O 02 : I 01 >-----| |--> O 03 : '--------'

in order to get there. Right?

Start out by assuming you can do it by placing four of them side by side:

: ,-------------------------------, : | ,----, | : ENA >-----| ENA >--| |---|--> O 00 : | | |---|--> O 01 : | I00 >--| |---|--> O 02 : | I01 >--| |---|--> O 03 : | '----' | : | ,----, | : | ENA >--| |---|--> O 04 : | | |---|--> O 05 : | I00 >--| |---|--> O 06 : | I01 >--| |---|--> O 07 : | '----' | : | ,----, | : | ENA >--| |---|--> O 08 : | | |---|--> O 09 : | I00 >--| |---|--> O 10 : I 00 >-----| I01 >--| |---|--> O 11 : | '----' | : I 01 >-----| ,----, | : | ENA >--| |---|--> O 12 : I 02 >-----| | |---|--> O 13 : | I00 >--| |---|--> O 14 : I 03 >-----| I01 >--| |---|--> O 15 : | '----' | : '-------------------------------'

Next, I think you might first guess that if you wire up all the ENA lines from each of the four individual decoders to the single ENA line for your logic block, that should handle the enable function requirement:

: ,-------------------------------, : | ,----, | : ENA >-----|------------+---------| |---|--> O 00 : | | | |---|--> O 01 : | | I00 >--| |---|--> O 02 : | | I01 >--| |---|--> O 03 : | | '----' | : | | ,----, | : | +---------| |---|--> O 04 : | | | |---|--> O 05 : | | I00 >--| |---|--> O 06 : | | I01 >--| |---|--> O 07 : | | '----' | : | | ,----, | : | +---------| |---|--> O 08 : | | | |---|--> O 09 : | | I00 >--| |---|--> O 10 : I 00 >-----| | I01 >--| |---|--> O 11 : | | '----' | : I 01 >-----| | ,----, | : | '---------| |---|--> O 12 : I 02 >-----| | |---|--> O 13 : | I00 >--| |---|--> O 14 : I 03 >-----| I01 >--| |---|--> O 15 : | '----' | : '-------------------------------'

But that won't work. Do you see why? The disabling function would work just fine, but what happens when you enable things? All four of the decoders will be enabled and whatever they might have at their I00 and I01 inputs will decide which of the outputs will be active. Which means you will have _four_ active lines out. And you don't want that. You only want just one enabled.

Which brings us to needing some way to imagine only activating just one of those four, at a time. Not all four of them.

gee! What a perfect application for .... a decoder! We need to somehow decode which of the four is active and to disable all of the rest. And a 2-to-4 decoder is a perfect fit for that:

: ,----------------------------------, : | ,----, | : ENA >--| ,----------| |---|--> O 00 : | | | |---|--> O 01 : | | I00 >--| |---|--> O 02 : | | I01 >--| |---|--> O 03 : | | '----' | : | | ,----, | : | | ,--------| |---|--> O 04 : | ,----, | | | |---|--> O 05 : |ENA>--| |--' | I00 >--| |---|--> O 06 : | | |----' I01 >--| |---|--> O 07 : |I00>--| |----, '----' | : |I01>--| |--, | ,----, | : | '----' | '--------| |---|--> O 08 : | | | |---|--> O 09 : | | I00 >--| |---|--> O 10 : I 00 >--| | I01 >--| |---|--> O 11 : | | '----' | : I 01 >--| | ,----, | : | '----------| |---|--> O 12 : I 02 >--| | |---|--> O 13 : | I00 >--| |---|--> O 14 : I 03 >--| I01 >--| |---|--> O 15 : | '----' | : '----------------------------------'

Now, you can see that only one of the original four can be enabled at any one time. And, if the fifth decoder's ENA line is inactivated, then none of its outputs will be activated and therefore none of the four chips will be activated. We've achieved the desire to have at most one of the original four decoders activated and, sometimes, none of them. But now there is no way for more than one to be active. Much better.

Now, we just tie up the enable line:

: ,----------------------------------, : | ,----, | : ENA >--|---, ,----------| |---|--> O 00 : | | | | |---|--> O 01 : | | | I00 >--| |---|--> O 02 : | | | I01 >--| |---|--> O 03 : | | | '----' | : | | | ,----, | : | | | ,--------| |---|--> O 04 : | | ,----, | | | |---|--> O 05 : | '--| |--' | I00 >--| |---|--> O 06 : | | |----' I01 >--| |---|--> O 07 : |I00>--| |----, '----' | : |I01>--| |--, | ,----, | : | '----' | '--------| |---|--> O 08 : | | | |---|--> O 09 : | | I00 >--| |---|--> O 10 : I 00 >--| | I01 >--| |---|--> O 11 : | | '----' | : I 01 >--| | ,----, | : | '----------| |---|--> O 12 : I 02 >--| | |---|--> O 13 : | I00 >--| |---|--> O 14 : I 03 >--| I01 >--| |---|--> O 15 : | '----' | : '----------------------------------'

Getting closer. You've already read DJ Delorie mentioning about using higher order bits to select devices and then to pass on the lower order bits for further decoding. Well, that is what now makes sense. We need to decide _which_ of the four original decoders (those tied directly to the output lines) should be enabled and then pass on the lower order bits. So, we choose to use the upper two bits of the four (namely, I02 and I03) to tell us which of the four original decoders to activate:

: ,----------------------------------, : | ,----, | : ENA >--|---, ,----------| |---|--> O 00 : | | | | |---|--> O 01 : | | | I00 >--| |---|--> O 02 : | | | I01 >--| |---|--> O 03 : | | | '----' | : | | | ,----, | : | | | ,--------| |---|--> O 04 : | | ,----, | | | |---|--> O 05 : | '--| |--' | I00 >--| |---|--> O 06 : | | |----' I01 >--| |---|--> O 07 : | ,----| |----, '----' | : | | ,--| |--, | ,----, | : | | | '----' | '--------| |---|--> O 08 : | | | | | |---|--> O 09 : | | | | I00 >--| |---|--> O 10 : I 00 >--| | | | I01 >--| |---|--> O 11 : | | | | '----' | : I 01 >--| | | | ,----, | : | | | '----------| |---|--> O 12 : I 02 >--|-' | | |---|--> O 13 : | | I00 >--| |---|--> O 14 : I 03 >--|---' I01 >--| |---|--> O 15 : | '----' | : '----------------------------------'

That will get that job done. Now for the final piece. Just tie all of the two addressing inputs for each of the original four decoders into parallel with each other and bring them over to the remaining two lines:

: ,----------------------------------, : | ,----, | : ENA >--|---, ,----------| |---|--> O 00 : | | | | |---|--> O 01 : | | | ,-----| |---|--> O 02 : | | | | ,--| |---|--> O 03 : | | | | | '----' | : | | | | | ,----, | : | | | ,--------| |---|--> O 04 : | | ,----, | | | | | |---|--> O 05 : | '--| |--' | +-----| |---|--> O 06 : | | |----' | +--| |---|--> O 07 : | ,----| |----, | | '----' | : | | ,--| |--, | | | ,----, | : | | | '----' | '--------| |---|--> O 08 : | | | | | | | |---|--> O 09 : | | | | +-----| |---|--> O 10 : I 00 >--|-|-|------, | | +--| |---|--> O 11 : | | | | | | | '----' | : I 01 >--|-|-|---, | | | | ,----, | : | | | | | '----------| |---|--> O 12 : I 02 >--|-' | | | | | | |---|--> O 13 : | | | '--------+-----| |---|--> O 14 : I 03 >--|---' '--------------+--| |---|--> O 15 : | '----' | : '----------------------------------'

The reason why doing those last two bits in parallel is that you are selecting one of four in each group on the basis of the low-order bits. Of course, only one of the four decoders at the output will be enabled, so only one of those will be active at any one time. At most. Maybe none of them, if the ENA line is inactivated. But if you closely look at the situation, you will see that this is right and works as it should.

Jon

Reply to
Jonathan Kirwan

[snip]

Jon, VERY NICELY TAUGHT!

...Jim Thompson

--
|  James E.Thompson, P.E.                           |    mens     |
|  Analog Innovations, Inc.                         |     et      |
|  Analog/Mixed-Signal ASIC\'s and Discrete Systems  |    manus    |
|  Phoenix, Arizona            Voice:(480)460-2350  |             |
|  E-mail Address at Website     Fax:(480)460-2142  |  Brass Rat  |
|       http://www.analog-innovations.com           |    1962     |
             
     It\'s what you learn, after you know it all, that counts.
Reply to
Jim Thompson

I agree. Well done Jon.

The only thing that I would add is that often, the function blocks you encounter in real parts often have inverted inputs or outputs so you have to add inverters here or there to get things to match up. For example the enable input and the decoded outputs are active low in the

74X139.
--
James T. White
Reply to
James T. White

--
Since the OP doesn\'t seem to be dealing with real parts at the
moment, Jon\'s use of positive true logic throughout to _illustrate
the principle_ is, IMO, exemplary.

Just a nice, straightforward description of "This is how it works"
without throwing in a lot of confusing glue logic.
Reply to
John Fields

And then, you can relabel the I/Os, and clean it up even more:

;-)

Cheers! Rich

Reply to
Rich Grise

I must agree - the use of active low outputs can be *very* confusing to students who are trying to grasp a principle (I speak from experience here, having taught such things). Get the principle, then add the little 'features' that are there for historical and practical reasons.

Someone mentioned using programmable logic. In this particular original question, it can make everything quite clear

(I could have used case statements below, but I wanted to make the logic clear)

Let's define a 2 - 4 line decoder with a select input

module 2_4_decoder ( inA, inB, out0, out1, out2, out3, select ); input inA, inB, select; output out0, out1, out2, out3;

always @(inA or inB or select) begin if(select) // only set outputs active if selects active begin if(!inA & !inB) begin out0 = 1'b1; out1 = 1'b0; out2 = 1'b0; out3 = 1'b0; end else if (inA & !inB) begin if(!inA & !inB) begin out0 = 1'b0; out1 = 1'b1; out2 = 1'b0; out3 = 1'b0; end else if (!inA & inB) begin begin if(!inA & !inB) begin out0 = 1'b0; out1 = 1'b0; out2 = 1'b1; out3 = 1'b0; end else if (inA & inB) begin if(!inA & !inB) begin out0 = 1'b0; out1 = 1'b0; out2 = 1'b0; out3 = 1'b1; end end else begin // select not active, deselect all outputs out0 = 1'b0; out1 = 1'b0; out2 = 1'b0; out3 = 1'b0; end

endmodule

now let's define a 4-16 line decoder, using our previous decoder, in the same sense as the original question, with a master select

module 4_16_decode ( in[3:0], // do this as a subscripted object to save space out[15:0], select );

input in[3:0]; output out[15:0]; input select;

// instantiate 5 different instances of our 2-4 line decoder and hook it up

wire decode0; wire decode1; wire decode2; wire decode3; // decode which decoder to use

2_4_decoder decode_decoder // to decode which decoder ( .inA(in[2]), .inB(in[3]), .out0(decode0), .out1(decode1), .out2(decode2), .out3(decode3), .select(select) );

// now the actual output decoders

2_4_decoder decode_low4 // lowest four bits ( .inA(in[0]), .inB(in[1]), .out0(out[0]), .out1(out[1]), .out2(out[2]), .out3(out[3]), .select(decode0) );

2_4_decoder decode_4_7 // bits 4 through 7 ( .inA(in[0]), .inB(in[1]), .out0(out[4]), .out1(out[5]), .out2(out[6]), .out3(out[7]), .select(decode1) );

2_4_decoder decode_8_11 // bits 8 through 11 .inA(in[0]), .inB(in[1]), .out0(out[8]), .out1(out[9]), .out2(out[10]), .out3(out[11]), .select(decode2) );

2_4_decoder decode_12_15 // bits 12 through 15 ( .inA(in[0]), .inB(in[1]), .out0(out[12]), .out1(out[13]), .out2(out[14]), .out3(out[15]), .select(decode3) );

endmodule

Hope that helps too!

Cheers

PeteS

Reply to
PeteS

It would, but only if it were in VHDL. :P

Seriously, I would have started with a simpler Verilog version of the

2to4:

module decode_2_4( ENA, A, Y ); input ENA; input( 1:0 ) A; output( 3:0 ) Y; reg( 3:0 ) Y; reg( 2:0 ) ENA_A; always @( ENA or A ) begin case( {ENA,A} ) 3'b 100: Y= 4'b 0001; 3'b 101: Y= 4'b 0010; 3'b 110: Y= 4'b 0100; 3'b 111: Y= 4'b 1000; default: Y= 4'b 0000; endcase end endmodule;

Less wear and tear on the brain, I think, if I got that right.

Could do a for() loop and that might be better for a generic decoder module using parameters.

But all this side-tracks from what the OP needed, I suspect.

Jon

Reply to
Jonathan Kirwan

Woops... just:

endmodule

without the semicolon. Oh, well.

Jon

Reply to
Jonathan Kirwan

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.