![]() |
|
|
|||||||
![]() |
VHDL - Out of Range - simulation vs. synthesis |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi all,
I have the following piece of VHDL code which is not accepted in simulation but in synthesis: constant cCLUSTER : integer := 4; type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1 downto 0); signal ls_addr_cluster : cluster_type; process(Clk) begin if rising_edge(Clk) then if TxValid='1' then case Addr is when "00" => if cCLUSTER >= 1 then ls_addr_cluster(0) <= Addr; end if; when "01" => if cCLUSTER >=2 then ls_addr_cluster(1) <= Addr; end if; when "10" => if cCLUSTER >=3 then ls_addr_cluster(2) <= Addr; end if; when "11" => if cCLUSTER >=4 then ls_addr_cluster(3) <= Addr; end if; end case; end if; end if; end process; When using cCLUSTER=3 the simulation is aborted with the error message: "Index value 3 is out of range 2 downto 0". The if-condition seems not to keep Modelsim from checking the assignment "ls_addr_cluster(3) <= Addr;" although cCLUSTER is a constant definition. Synthesis does not complain ... How can I solve that problem ? Thank you for your opinion. Rgds Andre ALuPin@web.de |
|
|
|
|
#2 |
|
Posts: n/a
|
On Mar 5, 3:22 am, "ALu...@web.de" <ALu...@web.de> wrote:
> Hi all, > > I have the following piece of VHDL code which > is not accepted in simulation but in synthesis: > > constant cCLUSTER : integer := 4; > type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1 > downto 0); > signal ls_addr_cluster : cluster_type; > > process(Clk) > begin > if rising_edge(Clk) then > > if TxValid='1' then > > case Addr is > when "00" => if cCLUSTER >= 1 then > ls_addr_cluster(0) <= Addr; > end if; > when "01" => if cCLUSTER >=2 then > ls_addr_cluster(1) <= Addr; > end if; > when "10" => if cCLUSTER >=3 then > ls_addr_cluster(2) <= Addr; > end if; > when "11" => if cCLUSTER >=4 then > ls_addr_cluster(3) <= Addr; > end if; > end case; > > end if; > end if; > end process; > > When using cCLUSTER=3 the simulation is aborted with the error > message: "Index value 3 is out of range 2 downto 0". > The if-condition seems not to keep Modelsim from checking > the assignment "ls_addr_cluster(3) <= Addr;" although > cCLUSTER is a constant definition. Synthesis does not complain ... > How can I solve that problem ? > > Thank you for your opinion. > > Rgds > Andre It looks like your trying to store Addr in ls_addr_cluster, but limiting the size of ls_addr_cluster to below what might appear in Addr? This is a common issue in address decoding. Instead of a case statement, use a for-loop indexed on the range of the array: for i in ls_addr_cluster'range loop if i = unsigned(Addr) then ls_addr_cluster(i) <= Addr; exit; -- optional, speeds up sim end if; end loop; Whenever the size of an array is variable, it is almost never a good idea to use a case statement to access elements of it. Loop statements are unrolled for synthesis, so this becomes a sequence of if statements (the exit statements turns it into one big if-elsif- elsif... statement) The exit statement in this example will have no effect on synthesis (the if conditions are mutually exclusive anyway), but it terminates the loop in simulation once a match is found. Andy Andy |
|
|
|
#3 |
|
Posts: n/a
|
Hi Andy,
thank you for your clear explanation. Rgds Andre ALuPin@web.de |
|
|
|
#4 |
|
Posts: n/a
|
Hi Andy,
some additional question. How can I describe it as a loop when using the following addressing: Addr: IN std_logic_vector(3 DOWNTO 0); .... constant cCLUSTER : integer := 4; type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1 downto 0); signal ls_addr_cluster : cluster_type; process(Clk) begin if rising_edge(Clk) then if TxValid='1' then case Addr(3 DOWNTO 2) is when "00" => if cCLUSTER >= 1 then ls_addr_cluster(0) <= Addr(1 DOWNTO 0); end if; when "01" => if cCLUSTER >=2 then ls_addr_cluster(1) <= Addr(1 DOWNTO 0); end if; when "10" => if cCLUSTER >=3 then ls_addr_cluster(2) <= Addr(1 DOWNTO 0); end if; when "11" => if cCLUSTER >=4 then ls_addr_cluster(3) <= Addr(1 DOWNTO 0); end if; end case; end if; end if; end process; Rgds Andre ALuPin@web.de |
|
|
|
#5 |
|
Posts: n/a
|
USE ieee.numeric_std.ALL;
IF cCLUSTER-1 >= to_integer( unsigned( Addr(3 DOWNTO 2) ) ) THEN ls_addr_cluster(to_integer( unsigned( Addr(3 DOWNTO 2) ) )) <= Addr(1 DOWNTO 0); END IF; Kind regards, Pieter Hulshoff Pieter Hulshoff |
|
|
|
#6 |
|
Posts: n/a
|
On Mar 6, 5:31 am, "ALu...@web.de" <ALu...@web.de> wrote:
> Hi Andy, > > some additional question. How can I describe it as a loop when > using the following addressing: > > Addr: IN std_logic_vector(3 DOWNTO 0); > ... > constant cCLUSTER : integer := 4; > type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1 > downto 0); > signal ls_addr_cluster : cluster_type; > > process(Clk) > begin > if rising_edge(Clk) then > > if TxValid='1' then > > case Addr(3 DOWNTO 2) is > when "00" => if cCLUSTER >= 1 then > ls_addr_cluster(0) <= Addr(1 > DOWNTO 0); > end if; > when "01" => if cCLUSTER >=2 then > ls_addr_cluster(1) <= > Addr(1 DOWNTO 0); > end if; > when "10" => if cCLUSTER >=3 then > ls_addr_cluster(2) <= Addr(1 > DOWNTO 0); > end if; > when "11" => if cCLUSTER >=4 then > ls_addr_cluster(3) <= Addr(1 > DOWNTO 0); > end if; > end case; > > end if; > end if; > end process; > > Rgds > Andre You declared "cCLUSTER" to be a constant with a value of 4. Then in your case statements you have when "01" => if cCLUSTER >= 2 then... But AFAIK that's the same as when "01" => if 4 >= 2 then... So I'm confused. What are you trying to do??? -Dave Pollum Dave Pollum |
|
|
|
#7 |
|
Posts: n/a
|
Hi Pieter,
thank you for your proposal. @ Dave Generic Multiplexer of two-dimensional arrays Rgds Andre ALuPin@web.de |
|
|
|
#8 |
|
Posts: n/a
|
On Mar 6, 5:31 am, "ALu...@web.de" <ALu...@web.de> wrote:
> Hi Andy, > > some additional question. How can I describe it as a loop when > using the following addressing: > > Addr: IN std_logic_vector(3 DOWNTO 0); > ... > constant cCLUSTER : integer := 4; > type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1 > downto 0); > signal ls_addr_cluster : cluster_type; > > process(Clk) > begin > if rising_edge(Clk) then > > if TxValid='1' then > > case Addr(3 DOWNTO 2) is > when "00" => if cCLUSTER >= 1 then > ls_addr_cluster(0) <= Addr(1 > DOWNTO 0); > end if; > when "01" => if cCLUSTER >=2 then > ls_addr_cluster(1) <= > Addr(1 DOWNTO 0); > end if; > when "10" => if cCLUSTER >=3 then > ls_addr_cluster(2) <= Addr(1 > DOWNTO 0); > end if; > when "11" => if cCLUSTER >=4 then > ls_addr_cluster(3) <= Addr(1 > DOWNTO 0); > end if; > end case; > > end if; > end if; > end process; > > Rgds > Andre If you are asking what difference it makes if the addressed space is indicated by Addr(4 downto 0), it doesn't. Have the loop iterate on the elements of the array, and check to see if the value of the array (loop) index equals the value of Addr (independent of length of Addr). If it does, assign the element of the array, indexed with the loop index, not Addr. If you are asking how to control the width of Addr based on cCLUSTER, then you need to pass cCluster in as a generic on the entity, and specify the Addr port range in terms of that generic. If, on the other hand, you are wanting to declare cCluster based on the width of the Addr port, then you can use the Addr'length attribute and exponentiation to determine the value of cCluster. Andy Andy |
|
|
|
#9 |
|
Posts: n/a
|
Hi Andy,
thank you for your proposed different approaches. Rgds Andre ALuPin@web.de |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| need help in php displaying week range | saravana | General Help Related Topics | 0 | 04-08-2009 11:31 PM |
| Simulation question Issue | Rahul | MCITP | 9 | 06-30-2008 09:53 PM |
| synthesis error | sekhar_kollati | Hardware | 0 | 11-13-2007 04:48 AM |
| Post-Route Simulation does not give output for the first clock cycle Options | velocityreviews | Software | 0 | 04-17-2007 05:47 PM |
| simulation | Tom | MCITP | 0 | 04-05-2007 01:40 AM |