0

For an application I am creating I would like to use a decoder that helps write to one of 42 registers. In order to account for all possible registers, I need a 6 bit input since the ceiling of lg(42) is 6.

However, this will create a 6 to 64 decoder, leaving me with an extra 12 outputs that I do not know how to handle. I know that in VHDL I can write a case statement for it:

case input is
   when "000000" => output <= reg0;
   when "000001" => output <= reg1;
   .
   .
   .
   when others => output <= ???;
end case;

Hopefully everything else will be designed so that an input > 41 does not occur, but how should the code be written to handle that case? Is there a way to handle it without stopping the application some how? Or, as an alternative, is there a way to write a decoder that has only 42 outputs?

AdamMc331
  • 16,492
  • 10
  • 71
  • 133

1 Answers1

3

An easier way to write this is:

type regs_type is array (integer range <>) of std_logic_vector(7 downto 0);
signal regs : regs_type (0 to 41) := (others => (others => '0'));

...

output <= regs(to_integer(unsigned(input));

Assuming 'input' is an std_logic_vector, and that your registers are 8-bits wide.

Then use the regs array for your registers 0-41. I suppose if you wanted to be explicit about registers 42+, you could create an array of size 64, and leave the upper elements unconnected, but I believe the above code would achieve the same thing.

If your registers actually have meaningful names, not just reg0 etc, you can have a separate block of code connecting these to the regs array, example:

regs(0) <= setup_reg;
regs(1) <= data_out;

and so on. If I was doing it this way, I would have defined constants for the regs index values, example:

constant SETUP_REG_ADDRESS : integer := 0;
constant DATA_OUT_ADDRESS : integer := 1;

...

regs(SETUP_REG_ADDRESS) <= setup_reg;
regs(DATA_OUT_ADDRESS) <= data_out;

Alternatively, if you wanted to keep the case statement, you could write your others clause as

when others => output <= (others => '-');

This 'don't care' value allows the tools to do whatever is the most efficient in these cases that you believe to be unreachable anyway. If you were concerned about something undefined being assigned to output if input somehow did exceed 41, you could always replace the '-' with a '0'.

scary_jeff
  • 4,314
  • 13
  • 27
  • I like this idea. Originally the structure was designed so that the decoder and the register were separate components, and the output of the decoder determined which register to read to but this looks a little cleaner. Regarding your don't care output comment: the decoder was set to have an enable where it would output all 0s if the enable was low. I suppose I could also just output all 0s if the value is > 41? – AdamMc331 Mar 26 '15 at 16:08
  • 1
    If I understand you correctly, I think you could most easily achieve that by setting the size of the `regs` array to be 64 in the first example, or with the `(others => '0')` in the second. To implement an `enable`, I think both methods would need and `if/then/else` to set `output` to all zeroes. – scary_jeff Mar 26 '15 at 16:18