简体   繁体   中英

VHDL generic comparison and synthesis

I have a problem when synthesizing code with generics : My entity is :

entity MyEntity is
  generic(
  OUTWIDTH : integer range 8 to 64;
  NBREG : integer range 2 to 8);
  port(
    port1 ....
    port2 ....
  );  
end entity;

architecture rtl of MyEntity is
constant KEEP_VAL : std_logic_vector(OUTWIDTH/8-1 downto 0) := (others=>'1'); -- used to compare my signal with (others=>'1')
signal keep : std_logic_vector((NBREG*OUTWIDTH/8)-1 downto 0);

begin

process(clk)
variable v1 : integer range 0 to NBREG-1
begin
if(rising_edge(clk)) then
   --SOME CODE
   ....
   ....
   -- The comparison I want to do :
  if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL) then  -- the line where the error appears
       -- DO sthg
end if;
end process;
end rtl;

To resume, I want to know if all the bits of a signal with a generic width (OUTWIDTH) are '1'. The previous code works well in simulations but doesn't whant to be synthesized. synplify for Libero : @E: CD289 : Expecting constant expression

I assume I could do it with a function (for loop on each bit and compare with '1') but is there an other "direct" option ?

Thank you.

Some synthesizers won't be able to use a non-constant value to dictate the range of a slice. One thing (of several) that you can do is map your array into a 2d array and use your non constant index to access what you want without any special slicing.

type keep_sliced_type is array(natural range <>) of std_logic_vector(outwidth/8-1 downto 0);
signal keep_sliced : keep_sliced_type(0 to nbreg-1);

...

g_map : for i in 0 to nbreg-1 generate
begin
    keep_sliced(i) <= keep(i*outwidth/8+outwidth/8-1 downto i*outwidth/8); --range is composed entirely of constants
end generate;

...

    if keep_sliced(v1)=keep_val then --replaces your erroring line

Furthermore, using variables is usually a bad idea, but I won't get too deep into that here. Fair warning, I just wrote this code in the answer box. It may have minor syntax errors.

Altough you question is not supported by a minimal complete verifiable example , thus it is difficult to properly help you, I can make an assumption.

First off: it is very easy to write VHDL that simulates correctly, but will not synthesize. You have to write VHDL specifically for synthesis.

The problem the synthesizer is giving is likely caused by the variable v1 . It is kind of difficult to synthesize this line:

if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL)

This single line combines variable(=asynchronous) arithmetic (eg v1*(OUTWIDTH/8) with a multiplexer and a comparison operation. How would you want to see that realized in logic? First multiplex, Then compare? All compare and then select the correct result?

Likely it's better to separate the operations: implement a multiplexer (with a select using a signal, not a variable) and a comparator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM