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.

Questions/issues with generators and partial signal assignment.

Status
Not open for further replies.

DarkInsanePyro

Newbie level 5
Joined
Oct 17, 2012
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,397
Hey everyone. I have a few more questions regarding VHDL and the quirks it seems to come with. I am -still- working on the ALU design that I posted about before but I changed my approach quite a bit. Eventually I will have to give up and declare everything manually but I wanted to make the design as dynamic as possible. Unfortunately the first change was converting the functions into components to grant flexible number of outputs rather than declaring a new custom type record. This came with a problem, where components cannot be utilzied in a process block which makes sense. Had to learn about generators (generate).

The current main issue staring me in the face is partial signal assignment where I want to assign a value to a sub-portion of a vector signal. The remaining unset bits will be asserted a value with the "others" keyword. This makes sense in my head but the compiler isn't liking it and I was hoping you could help me.

This is the code that I am having trouble with. The problem is that I am not sure how to synthesize an expression which will assert A to int_valuematrix where the value of "n" will declare the offset from right justification. I swear all the examples online are simple and have no potential to help in this situation, though it would help if you have a good (better) resource. I don't feel like I am doing anything crazy yet though I could be wrong.
Code:
library ieee;
use ieee.std_logic_1164.all;


entity Multiplier is
	generic(
		WidthA			:	integer	:= 3;
		WidthB			:	integer	:= 3
		);
		
	port(
		-- inputs
		A					:	in		std_logic_vector(WidthA-1 downto 0);
		B					:	in		std_logic_vector(WidthB-1 downto 0);
		
		-- outputs
		Q					:	out	std_logic_vector((WidthA+WidthB)-1 downto 0)
		);
		
end Multiplier;

architecture Multiplier_RTL of Multiplier is
	--------------------------------
	-- Component Dependencies
	--------------------------------
	component Adder
		generic (
			Width : integer := 3
			);
		port (
			A,B			: in	std_logic_vector(Width-1 downto 0);
			Cin			: in	std_logic;
			Q				: out	std_logic_vector(Width-1 downto 0);
			CarryBus		: out	std_logic_vector(Width downto 0);
			Cout			: out	std_logic
			);
	end component;
	
	--------------------------------
	-- Local Type Declarations
	--------------------------------
	subtype ExtendedBus is std_logic_vector(WidthA+WidthB-1 downto 0);
	type ValueMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	type SubresultMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	--subtype InputTerm is std_logic_vector(WidthA-1 downto 0);
	--type DataMatrix is array (WidthA+WidthB-1 downto 0) of InputTerm;
	
	--------------------------------
	-- Internal Signals
	--------------------------------
	signal int_valuematrix	: ValueMatrix;
	signal int_subresultmatrix : SubresultMatrix;
	
begin
	-- generate the value table
	gen_values: for n in B'reverse_range generate
		int_valuematrix(n)(n+A'left downto n+A'right) <= A;
		int_valuematrix(n) <= (others => '0');
	end generate;
	
	Q <= int_valuematrix(1);
	
	-- generate the masking table which enables/disables each adder 'cell'
	--gen_mask: for n in 2 downto 0 generate
	--	int_maskmatrix(n)(n+WidthB-1 downto n) <= (others => B(n));
	--	int_maskmatrix(n) <= (others => '0');
	--end generate;

	-- generate the table of additions
	--u1:	Adder generic map (Width => 3) port map(A=>"000"&A, B=>int_maskmatrix(0), Cin=>'0');
end Multiplier_RTL;


The current full source code as it stands in a non-working condition... just for reference if need be.
Code:
--============================================================
--= FullAdder
--============================================================
library ieee;
use ieee.std_logic_1164.all;


entity FullAdder is
	port(
		-- inputs
		A, B, Cin		:	in		std_logic;
		
		-- outputs
		Q, Cout			:	out	std_logic
		);
end FullAdder;


architecture FullAdder_RTL of FullAdder is
begin
	Q <= A xor B xor Cin;
	Cout <= (A and B) or (A and Cin) or (B and Cin);
end FullAdder_RTL;


--============================================================
--= Adder
--============================================================
library ieee;
use ieee.std_logic_1164.all;


entity Adder is
	generic(
		Width				:	integer := 3
		);
		
	port(
		-- inputs
		A, B				:	in		std_logic_vector(Width-1 downto 0);
		Cin				:	in		std_logic;
		
		-- outputs
		Q					:	out	std_logic_vector(Width-1 downto 0);
		CarryBus			:	out	std_logic_vector(Width downto 0);
		Cout				:	out	std_logic
		);
end Adder;


architecture Adder_RTL of Adder is
	signal int_carry : std_logic_vector(Width downto 0);
	signal int_result : std_logic_vector(Width-1 downto 0);
	component FullAdder port (A,B,Cin : in std_logic; Q,Cout : out std_logic); end component;
begin
	int_carry(0) <= Cin;
	gen: for i in Width-1 downto 0 generate
		fa:	FullAdder port map(A=>A(i), B=>B(i), Cin=>int_carry(i), Q=>int_result(i), Cout=>int_carry(i+1));
	end generate;
	Q <= int_result;
	Cout <= int_carry(int_carry'left);
	CarryBus <= int_carry;
end Adder_RTL;


--============================================================
--= Inverter
--============================================================
library ieee;
use ieee.std_logic_1164.all;


entity Inverter is
	generic(
		Width				:	integer := 3
		);
		
	port(
		-- inputs
		A					: in	std_logic_vector(Width-1 downto 0);
		
		-- outputs
		Q					: out	std_logic_vector(Width-1 downto 0)
		);
end Inverter;


architecture Inverter_RTL of Inverter is
	signal mask : std_logic_vector(Width-1 downto 0) := (others => '1');
begin
	Q <= A xor mask;
end Inverter_RTL;


--============================================================
--= Multiplier
--============================================================
library ieee;
use ieee.std_logic_1164.all;


entity Multiplier is
	generic(
		WidthA			:	integer	:= 3;
		WidthB			:	integer	:= 3
		);
		
	port(
		-- inputs
		A					:	in		std_logic_vector(WidthA-1 downto 0);
		B					:	in		std_logic_vector(WidthB-1 downto 0);
		
		-- outputs
		Q					:	out	std_logic_vector((WidthA+WidthB)-1 downto 0)
		);
		
end Multiplier;

architecture Multiplier_RTL of Multiplier is
	--------------------------------
	-- Component Dependencies
	--------------------------------
	component Adder
		generic (
			Width : integer := 3
			);
		port (
			A,B			: in	std_logic_vector(Width-1 downto 0);
			Cin			: in	std_logic;
			Q				: out	std_logic_vector(Width-1 downto 0);
			CarryBus		: out	std_logic_vector(Width downto 0);
			Cout			: out	std_logic
			);
	end component;
	
	--------------------------------
	-- Local Type Declarations
	--------------------------------
	subtype ExtendedBus is std_logic_vector(WidthA+WidthB-1 downto 0);
	type ValueMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	type SubresultMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	--subtype InputTerm is std_logic_vector(WidthA-1 downto 0);
	--type DataMatrix is array (WidthA+WidthB-1 downto 0) of InputTerm;
	
	--------------------------------
	-- Internal Signals
	--------------------------------
	signal int_valuematrix	: ValueMatrix;
	signal int_subresultmatrix : SubresultMatrix;
	
begin
	-- generate the value table
	gen_values: for n in B'reverse_range generate
		int_valuematrix(n)(n+A'left downto n+A'right) <= A;
		int_valuematrix(n) <= (others => '0');
	end generate;
	
	Q <= int_valuematrix(1);
	
	-- generate the masking table which enables/disables each adder 'cell'
	--gen_mask: for n in 2 downto 0 generate
	--	int_maskmatrix(n)(n+WidthB-1 downto n) <= (others => B(n));
	--	int_maskmatrix(n) <= (others => '0');
	--end generate;

	-- generate the table of additions
	--u1:	Adder generic map (Width => 3) port map(A=>"000"&A, B=>int_maskmatrix(0), Cin=>'0');
end Multiplier_RTL;



--============================================================
--= Top Level - SimpleALU
--============================================================
library ieee;
use ieee.std_logic_1164.all;


entity SimpleALU is
	port(
		-- inputs
		A, B, S			:	in		std_logic_vector(2 downto 0);
		
		-- outputs
		Q					:	out	std_logic_vector(5 downto 0);
		O					:	out	std_logic;
		C					:	out	std_logic
		);
end SimpleALU;


architecture SimpleALU_RTL of SimpleALU is
	component Adder
		generic (
			Width : integer := 3
			);
		port (
			A,B			: in	std_logic_vector(Width-1 downto 0);
			Cin			: in	std_logic;
			Q				: out	std_logic_vector(Width-1 downto 0);
			CarryBus		: out	std_logic_vector(Width downto 0);
			Cout			: out	std_logic
			);
	end component;
	
	component Inverter
		generic(
			Width : integer := 3
			);
		port (
			A				: in	std_logic_vector;
			Q				: out	std_logic_vector
			);
	end component;
	
	component Multiplier
		generic(
			WidthA	:	integer := 3;
			WidthB	:	integer := 3
			);
		port(
			A			:	in		std_logic_vector(WidthA-1 downto 0);
			B			:	in		std_logic_vector(WidthB-1 downto 0);
			Q			:	out	std_logic_vector(WidthA+WidthB-1 downto 0)
			);
	end component;
	
	signal int_carrybus	:	std_logic_vector(3 downto 0);
begin
--	u1:	Adder port map(A=>A, B=>B, Cin=>'0', Q=>Q(2 downto 0), CarryBus=>int_carrybus);
--	u2:	Inverter port map(A=>A, Q=>Q(5 downto 3));
--	C <= int_carrybus(int_carrybus'left);
--	O <= int_carrybus(int_carrybus'left) xor int_carrybus(int_carrybus'left-1);
	u1:	Multiplier port map(A=>A, B=>B, Q=>Q);
end SimpleALU_RTL;

Sorry if there is missing information. Wrote this post a while ago but campus seems to have connection issues to your server especially during posting.
 

You didn't say what error message you got from the compiler.
You seem to have multiple drivers, so you can try this (not tested by me):


Code VHDL - [expand]
1
2
3
4
5
6
7
gen_values: for n in B'reverse_range generate
  process(A)
  begin
    int_valuematrix(n) <= (others => '0');
    int_valuematrix(n)(n+A'left downto n+A'right) <= A;
  end process;
end generate;

 

With your suggestion I synthesized it and got the warning:
:1369 - "C:\Users\DarkPrince\Documents\Xilinx\Lab2_SimpleALU\SimpleALU.vhd" Line 154: Possible infinite loop; process does not have a wait statement
I haven't tried it yet, in the middle of lecture, but will later. What I don't understand is that this isn't a black-box synth. I know what I want and it shouldn't be impossible to create. Lol.
 

Are you sure you have "A" in the sensitivity list?


Code VHDL - [expand]
1
process(A)

 

Thanks that seems to work. I think I get it... that I need to use a process block. Wow this is starting to get a bit hard to comprehend on complex designs. Oh well.

I have another question... is there a way to declare a -new- logic vector in-line with an expression so I don't need to declare the 'int_valuematrix' variable? Basically generate a mask and shifted A value on the fly to be used further on in the design. Would make things cleaner.

You using the xcode tag to get syntax-highlighted code? Seemed to just not parse at all. Odd. Anyway, this code isn't complete and knowingly would not work now. Working through the indexing/logic of it now.

Code:
architecture Multiplier_RTL of Multiplier is
	--------------------------------
	-- Component Dependencies
	--------------------------------
	component Adder
		generic (
			Width : integer := 3
			);
		port (
			A,B			: in	std_logic_vector(Width-1 downto 0);
			Cin			: in	std_logic;
			Q				: out	std_logic_vector(Width-1 downto 0);
			CarryBus		: out	std_logic_vector(Width downto 0);
			Cout			: out	std_logic
			);
	end component;
	
	--------------------------------
	-- Local Type Declarations
	--------------------------------
	subtype ExtendedBus is std_logic_vector(WidthA+WidthB-1 downto 0);
	type ValueMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	type SubresultMatrix is array (WidthA+WidthB-1 downto 0) of ExtendedBus;
	--subtype InputTerm is std_logic_vector(WidthA-1 downto 0);
	--type DataMatrix is array (WidthA+WidthB-1 downto 0) of InputTerm;
	
	--------------------------------
	-- Internal Signals
	--------------------------------
	signal int_valuematrix	: ValueMatrix;
	signal int_subresultmatrix : SubresultMatrix;
	
begin

	-- generate the shifting value table
	gen_values: for n in B'range generate
		process (A)
			variable mask : std_logic_vector(WidthA+WidthB-1 downto 0);
		begin
			mask := (others => '0');
			mask(n+A'left downto n+A'right) := (others =>B(n));
			int_valuematrix(n) <= (others => '0');
			int_valuematrix(n)(n+A'left downto n+A'right) <= A and mask;
		end process;
	end generate;
	
	-- sum all of the nodes together
	gen_adders:	for n in B'range generate
		first: if (n = B'right) generate
		begin
			int_subresultmatrix(n) <= int_valuematrix(n);
		end generate first;
		
		other: if (n /= B'right) generate
		begin
			ua:	Adder port map(A=>int_valuematrix(n), B=>int_subresultmatrix(n), Cin=>'0', Q=>int_subresultmatrix(n+1));
		end generate other;
	end generate;
	
	Q <= int_valuematrix(1);
	
	-- generate the masking table which enables/disables each adder 'cell'
	--gen_mask: for n in 2 downto 0 generate
	--	int_maskmatrix(n)(n+WidthB-1 downto n) <= (others => B(n));
	--	int_maskmatrix(n) <= (others => '0');
	--end generate;

	-- generate the table of additions
	--u1:	Adder generic map (Width => 3) port map(A=>"000"&A, B=>int_maskmatrix(0), Cin=>'0');
end Multiplier_RTL;

Edit: of course because I want to get this turned in, I took a manual approach to the problem and it worked just like that. I still want to get this working dynamicially though. Example for A and B being a 3-bit input:
Code:
library ieee;
use ieee.std_logic_1164.all;


entity Multiplier is
	port(
		-- inputs
		A					:	in		std_logic_vector(2 downto 0);
		B					:	in		std_logic_vector(2 downto 0);
		
		-- outputs
		Q					:	out	std_logic_vector(5 downto 0)
		);
		
end Multiplier;


architecture Multiplier_RTL of Multiplier is
	--------------------------------
	-- Component Dependencies
	--------------------------------
	component Adder
		generic (
			Width : integer := 3
			);
		port (
			A,B			: in	std_logic_vector(Width-1 downto 0);
			Cin			: in	std_logic;
			Q				: out	std_logic_vector(Width-1 downto 0);
			CarryBus		: out	std_logic_vector(Width downto 0);
			Cout			: out	std_logic
			);
	end component;
	
	--------------------------------
	-- Local Type Declarations
	--------------------------------
	subtype ExtendedBus is std_logic_vector(5 downto 0);
	type ValueMatrix is array (2 downto 0) of ExtendedBus;

	--------------------------------
	-- Internal Signals
	--------------------------------
	signal int_subvalues : ValueMatrix;
	signal int_subresults : ValueMatrix;
	
begin

	-- generate a table of shifted 'A' values masked by the associated 'B[x]' bit
	process (A, B, int_subvalues)
		variable mask_0 : std_logic_vector(2 downto 0);
		variable mask_1 : std_logic_vector(2 downto 0);
		variable mask_2 : std_logic_vector(2 downto 0);
	begin
		int_subvalues <= (others => (others => '0'));
		mask_0 := (others => B(0));
		int_subvalues(0) <= "000" & (A and mask_0);
		mask_1 := (others => B(1));
		int_subvalues(1) <= "00" & (A and mask_1) & "0";
		mask_2 := (others => B(2));
		int_subvalues(2) <= "0" & (A and mask_2) & "00";
	end process;
	
	-- connect the adders together
	int_subresults(0) <= int_subvalues(0);
	u1:	Adder generic map (Width=>6) port map(A=>int_subvalues(1), B=>int_subresults(0), Cin=>'0', Q=>int_subresults(1));
	u2:	Adder generic map (Width=>6) port map(A=>int_subvalues(2), B=>int_subresults(1), Cin=>'0', Q=>int_subresults(2));
	
	-- debug
	Q <= int_subresults(2);
end Multiplier_RTL;
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top