Generic binary decoder in VHDL

OP (Company: None) #7357222
Rate this post
useful
not useful

I am trying to code a generic one-hot binary decoder in VHDL. The following is the current code that I have come up with:

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity address_decoder is
6
  generic(
7
    NUM_BITS: natural := 3);
8
  port(
9
    input: in std_logic_vector(NUM_BITS - 1 downto 0);
10
    output: out std_logic_vector((2 ** NUM_BITS) - 1 downto 0));
11
end address_decoder;
12

13
architecture structural of address_decoder is
14
begin
15
  G_OUTPUT: for i in 0 to (2 ** NUM_BITS) - 1 generate
16
    output(i) <= '1' when unsigned(input) = i else '0';
17
  end generate G_OUTPUT;
18
end structural;

This code generates a comparator (is-equal) in series with a multiplexer to choose between '0' or '1' according to the output of the comparator for each of the final output bits, as in inferred from the 'when' statement. However, if I use the following architecture, a decoder component will be correctly inferred, but also a latch for the output bits, which I presume is due to incomplete assignment to the output vector.

1
architecture structural of address_decoder is
2
begin
3
  -- Compiler nags the choice must be a constant.
4
  --output <= (to_integer(unsigned(input)) => '1', others => '0');
5

6
  -- Try this incomplete assignment instead.
7
  output(to_integer(unsigned(input))) <= '1';
8
end structural;

So my question is, if there is any way to produce only a primitive decoder component without latched output? or the above series of comparators and multiplexers are close enough equivalents of a binary decoder in gate level terms?

Attached files:
Moderator (Company: Titel) #7357344
Rate this post
useful
not useful

Devun R. wrote:

but also a latch for the output bits, which I presume is due to incomplete assignment to the output vector.

Your assumption is correct.

What about this:

1
  process (input) begin
2
     output <= (others=>'0'); 
3
     output(to_integer(unsigned(input))) <= '1';  
4
  end process;

First line in the process is a default assignment, the second overrides the default value because the last assignemt in process "wins".

OP (Company: None) #7357935
Rate this post
useful
not useful

Your suggestion produces quite the circuit I expected, but frankly I am self-studying the book "Circuit Design with VHDL" as a beginner and this question is part of the exercises from the chapter dedicated to combinational circuits, hence use of 'process' blocks are shunned throughout the chapter. Anyway, was just wondering if there are more straightforward solutions, and thank you for the hint and snippet explanation.

Moderator (Company: Titel) #7359964
Rate this post
useful
not useful

Devun R. wrote:

dedicated to combinational circuits, hence use of 'process' blocks are shunned throughout the chapter.

You mean "concurrent statements"? Because it is absolutely no problem to put combinational circuits (without a clock) into a process.

Anyway, was just wondering if there are more straightforward solutions

Your

output <= (to_integer(unsigned(input)) => '1', others => '0');

is an obviously a valid VHDL solution. The problem is, that only 5% of the whole VHDL syntax elements can be synthesized to hardware. And if so then usually restrictions like a "constant choice value" must be observed. The synthesizers user manual tells you what can be translated to hardware.

This flashing LED is running fine in the simulator:

LED <= not LED after 500 ms;

But the synthesizer will never produce hardware out of this simple line of code.

Reply

Please log in before posting.

or

Log in with Google account

Registration is free and takes only a minute.

Register now