EmbDev.net

Forum: FPGA, VHDL & Verilog Generic binary decoder in VHDL


von Devun R. (Company: None) (devun_rowan)


Attached files:

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?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


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".

: Edited by Moderator
von Devun R. (Company: None) (devun_rowan)


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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


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.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.