Binary to thermometric algorithm

  • Thread starter vishallko31@gmail.com
  • Start date
V

vishallko31@gmail.com

Guest
Hello

I am designing a binary to thermometric bit converter.
Just to emphasise:

for example: If I have a binary number 011 then I would want 3 bit to
go one. ie. 111. If the number is five(101) then five bits should be
set to 1 (11111).

Can someone suggest an area-efficient scheme to achieve the same?

Regards
Vishal
 
Use an N-bit counter, count for the binary number of cycles, and while
it's counting, shift a '1' into a 2^N bit shift register, when it's
done counting, the shift register contains the thermometric output.
This assumes the shift register is properly cleared and that 2^N clock
cycles are acceptable.
 
Hi

Thanks for the reply. I cannot use clock in my design. Im trying to
make this a purely combinational block.

Regard
vishal


jens wrote:
Use an N-bit counter, count for the binary number of cycles, and while
it's counting, shift a '1' into a 2^N bit shift register, when it's
done counting, the shift register contains the thermometric output.
This assumes the shift register is properly cleared and that 2^N clock
cycles are acceptable.
 
On 13 Jun 2006 09:47:54 -0700, "vishallko31@gmail.com"
<vishallko31@gmail.com> wrote:

Hello

I am designing a binary to thermometric bit converter.

for example: If I have a binary number 011 then I would want 3 bit to
go one. ie. 111. If the number is five(101) then five bits should be
set to 1 (11111).
So, if you have N bits of input, your output code has (2**N)-1 bits.

It's usually a very nice idea to describe such things as a recursive
function. The sun was shining yesterday and I've just found a
disastrous bug in a SystemVerilog simulator, so I'm feeling in
a good mood and therefore I'm going to post the whole of the
code. Recursive function, synthesisable test model (5 inputs
and 31 outputs), and a little test bench. It's left as a trivial
exercise for the student to document it :)

In FPGA architectures with 4-input LUTs, this 5-to-31 test model
takes only 1 LUT per output, plus two extra LUTs. I suspect
it will start to get bigger quite rapidly as the number of input
bits increases, but the logic is pretty simple and has no nasty
ripple chains. That's the beauty of recursive solutions - they
typically give you tree-structured hardware with minimal
effort from either you or the synthesis tool.

Enjoy.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------- package contains synthesisable function

library ieee;
use ieee.std_logic_1164.all;

package thermo is
function thermo_code(s: std_logic_vector) return std_logic_vector;
end package thermo;

package body thermo is
function thermo_code(s: std_logic_vector) return std_logic_vector is
variable sn: std_logic_vector(s'length-1 downto 0);
variable c: std_logic_vector(1 to 2**(s'length-1));
variable t: std_logic_vector(2 to 2**(s'length-1));
begin
assert s'length > 0
report "Can't process null vector"
severity failure;
if s'length = 1 then
return s;
else -- s'length > 1
sn := s;
t := thermo_code(sn(sn'left-1 downto 0));
if sn(sn'left) = '1' then
c := (others => '1');
return c & t;
else
c := (others => '0');
return t & c;
end if;
end if;
end function thermo_code;
end package body thermo;

------------------------- synthesisable design 5->31 bits

library ieee;
use ieee.std_logic_1164.all;
use work.thermo.all;

entity test_thermo is
port ( value: in std_logic_vector(4 downto 0);
code: out std_logic_vector(1 to 31) );
end entity test_thermo;

architecture A of test_thermo is
begin
code <= thermo_code(value);
end architecture A; -- of test_thermo

---------------------------- test bench

library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
use ieee.numeric_std.all;

entity top_test_thermo is end;
architecture Test of top_test_thermo is
signal value: std_logic_vector(4 downto 0);
signal code: std_logic_vector(1 to 31);
begin
dut: entity work.test_thermo port map (value, code);
process
variable L: line;
begin
for i in 0 to 31 loop
value <= std_logic_vector(to_unsigned(i, value'length));
wait for 1 ns;
write(L, value);
write(L, string'(" => "));
write(L, code);
writeline(output, L);
end loop;
wait;
end process;
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Hi Jonathan

Many thanks for the concept, advice and code. I shall try to implement
this and see. I need to do this for an 8-bit input

Another thing I was thinking was: Is it better (in terms of area and
power) to define a specific logic for each particular bit or it is ok
if we just use a function to accomplish this functionality. I mean what
would be a better way to go abt: Developing a logic for each 255
outputs (8-bit input) or using a function as yours.

Regards
Vishal


Jonathan Bromley wrote:
On 13 Jun 2006 09:47:54 -0700, "vishallko31@gmail.com"
vishallko31@gmail.com> wrote:

Hello

I am designing a binary to thermometric bit converter.

for example: If I have a binary number 011 then I would want 3 bit to
go one. ie. 111. If the number is five(101) then five bits should be
set to 1 (11111).

So, if you have N bits of input, your output code has (2**N)-1 bits.

It's usually a very nice idea to describe such things as a recursive
function. The sun was shining yesterday and I've just found a
disastrous bug in a SystemVerilog simulator, so I'm feeling in
a good mood and therefore I'm going to post the whole of the
code. Recursive function, synthesisable test model (5 inputs
and 31 outputs), and a little test bench. It's left as a trivial
exercise for the student to document it :)

In FPGA architectures with 4-input LUTs, this 5-to-31 test model
takes only 1 LUT per output, plus two extra LUTs. I suspect
it will start to get bigger quite rapidly as the number of input
bits increases, but the logic is pretty simple and has no nasty
ripple chains. That's the beauty of recursive solutions - they
typically give you tree-structured hardware with minimal
effort from either you or the synthesis tool.

Enjoy.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------------------- package contains synthesisable function

library ieee;
use ieee.std_logic_1164.all;

package thermo is
function thermo_code(s: std_logic_vector) return std_logic_vector;
end package thermo;

package body thermo is
function thermo_code(s: std_logic_vector) return std_logic_vector is
variable sn: std_logic_vector(s'length-1 downto 0);
variable c: std_logic_vector(1 to 2**(s'length-1));
variable t: std_logic_vector(2 to 2**(s'length-1));
begin
assert s'length > 0
report "Can't process null vector"
severity failure;
if s'length = 1 then
return s;
else -- s'length > 1
sn := s;
t := thermo_code(sn(sn'left-1 downto 0));
if sn(sn'left) = '1' then
c := (others => '1');
return c & t;
else
c := (others => '0');
return t & c;
end if;
end if;
end function thermo_code;
end package body thermo;

------------------------- synthesisable design 5->31 bits

library ieee;
use ieee.std_logic_1164.all;
use work.thermo.all;

entity test_thermo is
port ( value: in std_logic_vector(4 downto 0);
code: out std_logic_vector(1 to 31) );
end entity test_thermo;

architecture A of test_thermo is
begin
code <= thermo_code(value);
end architecture A; -- of test_thermo

---------------------------- test bench

library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
use ieee.numeric_std.all;

entity top_test_thermo is end;
architecture Test of top_test_thermo is
signal value: std_logic_vector(4 downto 0);
signal code: std_logic_vector(1 to 31);
begin
dut: entity work.test_thermo port map (value, code);
process
variable L: line;
begin
for i in 0 to 31 loop
value <= std_logic_vector(to_unsigned(i, value'length));
wait for 1 ns;
write(L, value);
write(L, string'(" => "));
write(L, code);
writeline(output, L);
end loop;
wait;
end process;
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On 13 Jun 2006 12:57:37 -0700, "vishallko31@gmail.com"
<vishallko31@gmail.com> wrote:

Many thanks for the concept, advice and code. I shall try to implement
this and see. I need to do this for an 8-bit input
Doesn't sound hard; the function is completely generic for number
of input bits :)

Another thing I was thinking was: Is it better (in terms of area and
power) to define a specific logic for each particular bit or it is ok
if we just use a function to accomplish this functionality. I mean what
would be a better way to go abt: Developing a logic for each 255
outputs (8-bit input) or using a function as yours.
I tried synthesising my solution into Altera Stratix (though I
think I would get the same results in any FPGA with 4-input LUTS)
for 8-bit input, 255-bit output. In ten seconds of synthesis runtime,
I got an implementation with 287 LUTs - that's an average of 1.25
LUTs per output bit - and a critical path with 3 levels of logic.

It is entirely possible that you could find a smaller and/or faster
solution by hand. You're welcome to try. Here are a few little
points that may or may not be relevant to the attempt:

* I wrote and tested the recursive function in twenty minutes.
I wonder how long it would take to write your
hand-crafted version?

* Having written the function, I can customise it for any bit width
in approximately thirty seconds of coding effort, merely by
wrapping it in an entity with the right ports. How long would
it take you to modify a hand-crafted 8-input version to work
as a 9-input version?

* A good synthesis tool will make a good (not necessarily perfect,
but good) implementation of my function in any FPGA or ASIC
architecture I choose. Would your hand-crafted version be
appropriate for any architecture except the one you optimised for?

Academic exercises to get the ultimate optimisation are at best
pointless if your automatic tools can do well enough to meet the
specification requirements, and they are usually counter-
productive because of the huge cost in engineering time and the
appalling inflexibility of the resulting optimised designs.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Hi jonathan

Thanks for the tips. I tried the code for 8 bits and it meets all my
requirements. As you suggested, I think it would be useless to try and
find out a logic for each bit.

Thanks once again forthe great help.
regards
Vishal


Jonathan Bromley wrote:
On 13 Jun 2006 12:57:37 -0700, "vishallko31@gmail.com"
vishallko31@gmail.com> wrote:

Many thanks for the concept, advice and code. I shall try to implement
this and see. I need to do this for an 8-bit input

Doesn't sound hard; the function is completely generic for number
of input bits :)

Another thing I was thinking was: Is it better (in terms of area and
power) to define a specific logic for each particular bit or it is ok
if we just use a function to accomplish this functionality. I mean what
would be a better way to go abt: Developing a logic for each 255
outputs (8-bit input) or using a function as yours.

I tried synthesising my solution into Altera Stratix (though I
think I would get the same results in any FPGA with 4-input LUTS)
for 8-bit input, 255-bit output. In ten seconds of synthesis runtime,
I got an implementation with 287 LUTs - that's an average of 1.25
LUTs per output bit - and a critical path with 3 levels of logic.

It is entirely possible that you could find a smaller and/or faster
solution by hand. You're welcome to try. Here are a few little
points that may or may not be relevant to the attempt:

* I wrote and tested the recursive function in twenty minutes.
I wonder how long it would take to write your
hand-crafted version?

* Having written the function, I can customise it for any bit width
in approximately thirty seconds of coding effort, merely by
wrapping it in an entity with the right ports. How long would
it take you to modify a hand-crafted 8-input version to work
as a 9-input version?

* A good synthesis tool will make a good (not necessarily perfect,
but good) implementation of my function in any FPGA or ASIC
architecture I choose. Would your hand-crafted version be
appropriate for any architecture except the one you optimised for?

Academic exercises to get the ultimate optimisation are at best
pointless if your automatic tools can do well enough to meet the
specification requirements, and they are usually counter-
productive because of the huge cost in engineering time and the
appalling inflexibility of the resulting optimised designs.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top