Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL synthesizable or not

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Hello,

Can the following be synthesized ?

DATA_O <= DATA_I ( ( 8 * counter ) - 1 downto 8 * ( counter - 1 ) ) ;

-- DATA_I is an input bus
-- DATA_O is an 8 bit wide output bus
-- "counter" is defined as a positive integer

If it can't - why not ?
 

why not try synthesising it yourself?

You may find some do better than others. I knwo what you want is a mux. And it should give you a mux.
I know Quartus used to fall over this exact code before (and may still, I havent checked recently) when Xilinx was perfectly happy with it.

---------- Post added at 18:06 ---------- Previous post was at 18:04 ----------

PS, you might do better with:
DATA_O <= DATA_I ( ( 8 * (counter+1) ) downto 8 * counter ) ;

Unless your bus has -ve indices, which is impossible with std_logic_vector or bit_vector, or your counter starts at 1.
 

My counter starts at 4 and goes down to 1. Then it resets back to 4...

" DATA_O <= DATA_I ( ( 8 * (counter+1) ) downto 8 * counter ) ; "
This isn't the same as my code because it yields a 9 bit wide vector...while mine is 8 bits.

"Unless your bus has -ve indices"
What do you mean by that ?
 

I just assumed counter started at 0.
With your setup (4 to 1) be aware that it may build an 8 to 1 mux, with unused inputs being set to any random thing (though they are not possible states).
 

So there shouldn't be a problem?

"Unless your bus has -ve indices"
What did you mean by that ?
 

having built it in Quartus, it actually uses 16-1 muxes. as is. It isnt any better if you use an intermediate signal that is (counter-1)

You get much better/tidier results with a select. Directly using a select creates 8-1 muxes. Using the intermediate counter-1 values uses only 4-1 muxes, but you get an extra adder.

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity mux_test is
   port (
    
    counter : in  integer range 1 to 4;
    d_in    : in  std_logic_vector(31 downto 0);
    d_out   : out std_logic_vector(7 downto 0)
  );
end entity;
  
architecture rtl of mux_test is
  
  signal cm1 : integer range 0 to 3;
  
begin
  
  --D_out <= d_in( 8*(cm1+1) -1 downto 8*cm1 );
  
  --cm1 <= counter - 1;
  
  mux : with counter select
    d_out <= d_in( 7 downto  0) when 1,
             d_in(15 downto  8) when 2,
             d_in(23 downto 16) when 3,
             d_in(31 downto 24) when others;
  
end rtl;


---------- Post added at 18:50 ---------- Previous post was at 18:47 ----------

"Unless your bus has -ve indices"
What did you mean by that ?

New libraries, like the fixed point libraries, and any array types you declare youself, allow -ve indices:

type my_array_t is array(integer range <>) of integer;
signal my_array : my_array_t(7 downto -7);

Std_logic_vector and bit_vector are defined (natural range <>) so only allow indeces of 0+.

With your origional code, if the counter goes to 0, it will try and access -ve elements of the d_in array, whcih is not possible with a std_logic_vector.
 

Sure it will work this way...
But I wanted to build a block that takes a long vector and strobes out vector segments:

these are the generics:
-- segment_width : positive range 1 to 8
-- number_of_segments : positive range 1 to 4

The size of the input vector will be: segment_width * number_of_segments
The size of each segment is: segment_width

Therefore I wrote it like that:

DATA_O <= DATA_I ( ( segment_width * counter ) - 1 downto segment_width * ( counter - 1 ) ) ;
-- while counter is defined as :
signal counter : positive range 1 to number_of_segments ;
-- "counter" equals to "number_of_segments" after reset and each time it decrements, a new segment of the long vector is strobed.

I wanted to keep it generic and not limit myself to 32/8 bits like you proposed in your code...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top