Address decoding

L

Laurent Pinchart

Guest
Hi everybody,

I have some experience with VHDL as a language, but not much with bigger
systems design and optimization.

I need to implement address decoding for read/write operations on registers.
I would like to know which of those two methods gives better results and
should be prefered (of course, ff there is a better method that I haven't
thought about, feel free to mention it :).

I would choose the first method, as the case can easily be mapped to
hardware, but I might be wrong.

Laurent Pinchart

-- CODE --

signal reg1: std_logic_vector(...);
signal reg2: std_logic_vector(...);
....
signal regn: std_logic_vector(...);

-- METHOD 1 --
process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
reg2 <= REG2_INIT_VAL;
...
regn <= REGn_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (wr_en = '1') then
case addr is
when "0000" => reg1 <= data;
when "0001" => reg2 <= data;
...
when "1111" => regn <= data;
end case;
end if;
end if;
end process;

-- METHOD 2 --

signal reg1_sel : std_logic;
signal reg2_sel : std_logic;
....
signal regn_sel : std_logic;

reg1_sel <= '1' when wr_en and addr = "0000" else
'0';
reg2_sel <= '1' when wr_en and addr = "0001" else
'0';
....
regn_sel <= '1' when wr_en and addr = "1111" else
'0';

process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (reg1_sel = '1') then
reg1 <= data;
end if;
end if;
end process;

....

process (clk, rst)
begin
if (rst = '1') then
regn <= REGn_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (regn_sel = '1') then
regn <= data;
end if;
end if;
end process;
 
- METHOD 1 --
process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
reg2 <= REG2_INIT_VAL;
...
regn <= REGn_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (wr_en = '1') then
case addr is
when "0000" => reg1 <= data;
when "0001" => reg2 <= data;
...
when "1111" => regn <= data;
end case;
end if;
end if;
end process;
Method 1 is the recommended approach, as it is more RTL.
Your Method 2 is more "schematic" and low level.
Synthesis tools are not that dumb!
-------------------------------------------
Ben Cohen Trainer, Consultant, Publisher (310) 721-4830
http://www.vhdlcohen.com/ vhdlcohen@aol.com
Author of following textbooks:
* Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004 isbn
0-9705394-6-0
* Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn
0-9705394-2-8
* Component Design by Example ", 2001 isbn 0-9705394-0-1
* VHDL Coding Styles and Methodologies, 2nd Edition, 1999 isbn 0-7923-8474-1
* VHDL Answers to Frequently Asked Questions, 2nd Edition, isbn 0-7923-8115
------------------------------------------------------------------------------
 
Laurent,

Hi! I guess it depends on what your target device would be. For ASICs both your
methods would be OK with preference to method #1 but for FPGAs you have to code
them differently.

Regards.

Jovit

Note: Remove '_' on email for personal correspondence.
 
I like method 1 for when I don't need to read
the registers back and a modification of
method 2 for when I do need to read the registers
back.

reg1_sel <= '1' when function_sel = '1' and addr = "0000" else '0';


process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
elsif rising_edge(Clk) then -- more recommended
if (wr_en = '1' and reg1_sel = '1') then
reg1 <= data;
end if;
end if;
end process;


Then for register readback:

ReadData <= (reg1 and reg1_sel) or
(reg2 and reg2_sel) or
....
(regn and regn_sel) ;


This assumes you have written an and function to
allow std_logic with std_logic_vector:
function and
(l:std_logic_vector; r: std_logic)
return std_logic_vector is
variable result : std_logic_vector(l'range) ;
begin
case r is
when '0' => result := (others => '0') ;
when '1' => result := l ;
when others => result := (others => 'X') ;
end case ;
return result ;
end ;

Note, this is anticipated to be in the VHDL-200X
langauge revision.

Cheers,
Jim Lewis
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Laurent Pinchart wrote:

Hi everybody,

I have some experience with VHDL as a language, but not much with bigger
systems design and optimization.

I need to implement address decoding for read/write operations on registers.
I would like to know which of those two methods gives better results and
should be prefered (of course, ff there is a better method that I haven't
thought about, feel free to mention it :).

I would choose the first method, as the case can easily be mapped to
hardware, but I might be wrong.

Laurent Pinchart

-- CODE --

signal reg1: std_logic_vector(...);
signal reg2: std_logic_vector(...);
...
signal regn: std_logic_vector(...);

-- METHOD 1 --
process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
reg2 <= REG2_INIT_VAL;
...
regn <= REGn_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (wr_en = '1') then
case addr is
when "0000" => reg1 <= data;
when "0001" => reg2 <= data;
...
when "1111" => regn <= data;
end case;
end if;
end if;
end process;

-- METHOD 2 --

signal reg1_sel : std_logic;
signal reg2_sel : std_logic;
...
signal regn_sel : std_logic;

reg1_sel <= '1' when wr_en and addr = "0000" else
'0';
reg2_sel <= '1' when wr_en and addr = "0001" else
'0';
...
regn_sel <= '1' when wr_en and addr = "1111" else
'0';

process (clk, rst)
begin
if (rst = '1') then
reg1 <= REG1_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (reg1_sel = '1') then
reg1 <= data;
end if;
end if;
end process;

...

process (clk, rst)
begin
if (rst = '1') then
regn <= REGn_INIT_VAL;
elsif (clk'Event and clk = '1') then
if (regn_sel = '1') then
regn <= data;
end if;
end if;
end process;
 

Welcome to EDABoard.com

Sponsor

Back
Top