Mapping all unused port slices together - entity

So,
I have a 32 bit port on one of my entities. This is actually made up of lots of smaller signals, all mapped into one register. In one example, when I instantiate it, I am only interested in 3 of the 32 signals. So, I map these accordingly, using a slice association (to a,b and c). I then want to assign the other 29 bits as zero. Is there a quicker way than having to write out several statements to cover all the remaining bits?
label: module1
port map(
reg_in(4) => a,
reg_in(7) => b,
reg_in(25)=> c,
reg_in(3 downto 0) => (others => '0'),
reg_in(6 downto 5) => (others => '0'),
reg_in(24 downto 8) => (others => '0'),
reg_in(31 downto 26) => (others => '0')
);

I would add an internal signal and connect that in the port map..
signal reg_assembly : std_logic_vector(31 downto 0);
...
reg_assembly <= (4 => a, 7 => b, 25 => c, others => '0');
label: module1
port map(
reg_in => reg_assembly
);

Related

VHDL Generic component declaration syntax error

I am having a simple generic single clock ram, and it has multiple generic values. However, I am getting a syntax error while declaring it.
The full structure of the code is:
entity main is
Port (
-- components
);
end main;
architecture Behavioral of main is
component xilinx_simple_dual_port_1_clock_ram is
generic (
RAM_WIDTH : integer, --< what is wrong here?
RAM_DEPTH : integer,
RAM_PERFORMANCE : string,
INIT_FILE : string
);
port
(
addra : in std_logic_vector(clogb2(RAM_DEPTH)-1) downto 0);
addrb : in std_logic_vector(clogb2(RAM_DEPTH)-1) downto 0);
dina : in std_logic_vector(RAM_WIDTH-1 downto 0);
clka : in std_logic;
wea : in std_logic;
enb : in std_logic;
rstb : in std_logic;
regceb: in std_logic;
doutb : out std_logic_vector(RAM_WIDTH-1 downto 0)
);
end component;
begin
ramA: xilinx_simple_dual_port_1_clock_ram
generic map (
RAM_WIDTH => 18,
RAM_DEPTH => 1024,
RAM_PERFORMANCE => "HIGH_PERFORMANCE",
INIT_FILE => ""
)
port map (
addra => addra,
addrb => addrb,
dina => dina,
clka => clka,
wea => wea,
enb => enb,
rsta => rsta,
regceb => regceb,
doutb => doutb
);
The other signals have been taken care of, including the port mapping to the bram module. I am getting a syntax error in the generic declaration.
You must give a generic a default value:
RAM_WIDTH : integer := 16;
-- ^
Also use ; not ,

VHDL small error when using a conditional signal assignment (when...else)

I'm currently working on a component that will perform addition or subtraction, depending on the user input. Right now, I am working on a process that handles the assignment of values to the internal signals which will be used by the internal components I am using. One problem that comes up is in the line when I'm assigning b_in with either the input b or the 2's complement of the input b. Two errors show up:
Error: COMP96_0015: addsub_16.vhd : (85, 17): ';' expected.
Error: COMP96_0046: addsub_16.vhd : (85, 41): Sequential statement expected.
The errors all reference to the line
b_in <= (b) when add_sub = '0' else (b_2scomp);
However when I placed this outside the process, no error occurred; only when it's inside the process. Can someone please help me why this is and what I can do to solve it?
In addition, I know that normally port mapping is done between the architecture declaration and the begin statement of the architecture. The reason I placed them after the process is because I needed to make sure that b_in has the right signal before the other components can use it. I don't know if this is the right way to do it, but I hope it is. This is just in case you guys are wondering why I'm dong it like this. Thanks
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity addsub_16 is
port(
c_in : in STD_LOGIC;
enable : in std_logic;
reset : in std_logic;
clk : in std_logic;
add_sub : in STD_LOGIC;
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
c_out : out STD_LOGIC;
result : out STD_LOGIC_VECTOR(15 downto 0)
);
end addsub_16;
architecture addsub_16 of addsub_16 is
--Signal declarations to hold internal vectors a, b g, p, and carry
signal a_in : std_logic_vector(15 downto 0); --Holds input a
signal b_in : std_logic_vector(15 downto 0); --Holds input b if add_sub = 0. Otherwise, holds b_2scomp
signal b_2scomp : std_logic_vector(15 downto 0); --Holds the 2s complement of b
signal prop_in : std_logic_vector(15 downto 0); --Holds the propagate signals from CLAs
signal gen_in : std_logic_vector(15 downto 0); --Holds the generate signals from CLAs
signal carry_in : std_logic_vector(15 downto 0); --Holds the carry signal from carry_logic
signal temp_result : std_logic_vector(15 downto 0); --Holds the temporary result to be driven out
--Component declarations
component cla_4bit
port (
a, b : in std_logic_vector(3 downto 0);
gen, prop : out std_logic_vector(3 downto 0)
);
end component;
component carry_logic
port (
g, p : in std_logic_vector(15 downto 0);
c_in : in std_logic;
carry : out std_logic_vector(15 downto 0);
c_out : out std_logic
);
end component;
--Actual behavior of module
begin
--b_in <= (b) when add_sub = '0' else (b_2scomp);
process (clk, reset)
begin
if reset = '0' then --At reset, everything is 0
a_in <= (others => '0');
b_in <= (others => '0');
b_2scomp <= (others => '0');
temp_result <= (others => '0');
elsif (rising_edge(clk)) then --Read in data to components on rising edge
if enable = '1' then --Only if enable is on
a_in <= a;
b_2scomp <= ((not b) + '1');
b_in <= (b) when add_sub = '0' else (b_2scomp);
end if;
elsif (falling_edge(clk)) then --Drive out values on falling edge
for i in 0 to 15 loop
temp_result(i) <= a_in(i) xor b_in(i) xor carry_in(i);
end loop;
result <= temp_result;
end if;
end process;
--portmapping of the components here. I don't think it'd be necessary to include them, but let me know if they are needed.
The ternary operator .. when .. else .. is not allowed inside a process block prior to VHDL-2008.
Solution 1: Write an ordinary if .. then .. else .. end if statement
Solution 2: Enable VHDL-2008 support in your tool chain
Solution 3: Write a function, lets say ite (if-then-else), which performs the ternary operation.

vhdl 4 bit vedic multiplier

entity fourbitmult is
Port ( a,b : in STD_LOGIC_VECTOR (3 downto 0);
p : out STD_LOGIC_VECTOR (7 downto 0));
end fourbitmult;
architecture Behavioral of fourbitmult is
component twobitmult
port(a,b:in std_logic_vector(1 downto 0);
p:out std_logic_vector (3 downto 0));
end component;
component rca
port(a,b:in std_logic_vector(3 downto 0);
s:out std_logic_vector(3 downto 0);
carry:out std_logic;
cin:in std_logic='0'
);
end component;
component halfadder
port(a,b:in std_logic;
s,c:out std_logic);
end component;
signal c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22: std_logic;
begin
m1:twobitmult port map(a(0),a(1),b(0),b(1),p(0),p(1),c1,c2);
m2:twobitmult port map(a(2),a(3),b(0),b(1),c15,c16,c17,c18);
m3:twobitmult port map(a(0),a(1),b(2),b(3),c19,c20,c21,c22);
m4:twobitmult port map(a(2),a(3),b(2),b(3),c7,c8,c9,c10);
r1:rca port map(c15,c16,c17,c18,c19,c20,c21,c22,c3,c4,c5,c6,c12);
r2:rca port map(c1,c2,c7,c8,c3,c4,c5,c6,p(2),p(3),p(4),p(5),c11);
c13<=c11 or c12;
h1:halfadder port map(c13,c9,p(6),c14);
h2:halfadder port map(c14,c10,p(7));
end Behavioral;
I wrote a VHDL code for the 4 bit vedic multiplier.
I am getting an error as:
Line 45. parse error, unexpected EQ, expecting SEMICOLON or CLOSEPAR"..
The syntax is perfectly right, I don't understand why it's an error. What could be wrong?
The syntax is perfectly right
Not quite.
cin:in std_logic='0'
Should be
cin: in std_logic := '0'
------------------^
You're also missing the context clause at the beginning:
library ieee;
use ieee.std_logic_1164.all;
You've deleted that and some header comments apparently, without indicating which line was line 45 (and it's the line excerpted above). Your example isn't quite a Minimal, Complete, and Verifiable example.
Syntax errors tend to show up easily when you use white space and indentation consistently and well.
Willing to make a claim about the semantics?
Addendum for " More actuals found than formals in port map"
As you've discovered you also have semantic errors as well as the above syntax error. While you didn't update your question, those errors can be explained here too.
The " More actuals found than formals in port map" for original lines 54 - 59 are because you don't have the same number of ports in the port map associations as are declared in the component declarations for twobitmult and rca instances.
You can cure these by using named association which allows you to use a formal's array port elements associated with an array base element type actual. (Allowing more association list entries than the number of ports).
Note that you appear to have an error with the rca component declaration, there are more port map associations shown than are possible by expanding array types.
It appears carry is intended to be an array type (and the following has been annotated to reflect that).
Also note that your array types in your components are declared with port element indexes in a descending order and you associate them with ascending order elements of entity fourbitmult array type ports.
Should you be able to use slices of the actuals with the same range direction as they are declared the association list entry could be simplified as a => a(1 downto 0), for example. The same holds true for other places you can connect slice actuals.
So making the number of ports match by using formal elements:
library ieee;
use ieee.std_logic_1164.all;
entity fourbitmult is
port (
a,b: in std_logic_vector (3 downto 0);
p: out std_logic_vector (7 downto 0));
end fourbitmult;
architecture behavioral of fourbitmult is
component twobitmult
port (
a,b: in std_logic_vector (1 downto 0);
p: out std_logic_vector (3 downto 0)
);
end component;
component rca
port (
a,b: in std_logic_vector (3 downto 0);
s: out std_logic_vector (3 downto 0);
carry: out std_logic_vector (3 downto 0); -- std_logic;
cin: in std_logic := '0' -- formerly line 45
);
end component;
component halfadder
port (
a,b: in std_logic;
s,c: out std_logic
);
end component;
signal c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,
c13,c14,c15,c16,c17,c18,c19,c20,c21,c22: std_logic;
begin
m1:
twobitmult
port map (
-- a(0),a(1),b(0),b(1),p(0),p(1),c1,c2
a(1) => a(0),
a(0) => a(1),
b(1) => b(0),
b(0) => b(1),
p(3) => p(0),
p(2) => p(1),
p(1) => c1,
p(0) => c2
);
m2:
twobitmult
port map (
-- a(2),a(3),b(0),b(1),c15,c16,c17,c18
a(1) => a(2),
a(0) => a(3),
b(1) => b(0),
b(0) => b(1),
p(3) => c15,
p(2) => c16,
p(1) => c17,
p(0) => c18
);
m3:
twobitmult
port map (
-- a(0),a(1),b(2),b(3),c19,c20,c21,c22
a(1) => a(0),
a(0) => a(1),
b(1) => b(2),
b(0) => b(3),
p(3) => c19,
p(2) => c20,
p(1) => c21,
p(0) => c22
);
m4:
twobitmult
port map (
-- a(2),a(3),b(2),b(3),c7,c8,c9,c10
a(1) => a(2),
a(0) => a(3),
b(1) => b(2),
b(0) => b(3),
p(3) => c7,
p(2) => c8,
p(1) => c9,
p(0) => c10
);
r1:
rca
port map (
--c15,c16,c17,c18,c19,c20,c21,c22,c3,c4,c5,c6,c12
a(3) => c15,
a(2) => c16,
a(1) => c17,
a(0) => c18,
b(3) => c19,
b(2) => c20,
b(1) => c21,
b(0) => c22,
carry(3) => c3,
carry(2) => c4,
carry(1) => c5,
carry(0) => c6,
cin => c12
);
r2:
rca
port map (
-- c1,c2,c7,c8,c3,c4,c5,c6,p(2),p(3),p(4),p(5),c11
a(3) => c1,
a(2) => c2,
a(1) => c7,
a(0) => c8,
b(3) => c3,
b(2) => c4,
b(1) => c5,
b(0) => c6,
carry(3) => p(2),
carry(2) => p(3),
carry(1) => p(4),
carry(0) => p(5),
cin => c11
);
c13 <= c11 or c12;
h1:
halfadder
port map (
c13,c9,p(6),c14
);
h2:
halfadder
port map (
c14,c10,p(7)
);
end behavioral;
This analyzes, but without the entity/architecture pairs for the declared components can't be elaborated, nor the functionality verified.

VHDL writing to file

I have a simple task to do. I have a moudule hilbert which is unit under test. I just want to write "real_o" and "img" in a file on every rising edge of clock like
1 2
1 3
0 -2
0 -1
1 0
1 4
Where left column is real_o and right is img.
test bench code is
COMPONENT hilbert
PORT(
clk : IN std_logic;
reset : IN std_logic;
x : IN std_logic_vector(15 downto 0);
real_o : out STD_LOGIC;
img : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal x : std_logic_vector(15 downto 0) := (others => '0');
--Outputs
signal img : std_logic_vector(3 downto 0);
signal real_o : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: hilbert PORT MAP (
clk => clk,
reset => reset,
x => x,
real_o => real_o,
img => img
);
Can someone tell me steps to write real_o and img signals columnwise in a file?
Your question is not specific enough for this site. People will help you, but only if you have a specific problem that you are trying to solve. "Can you tell me what steps to do whatever" is too vague.
I will link you to an example that I created for file IO in VHDL that might help you. If you have any specific problems feel free to create a new post about them.
VHDL Writing to File

FPGA BRAM Stack Implementation Xilinx 7-Series

I am creating a stack based on the artix-7 fabric on the zynq soc. To create the stack I want to use the BRAM, I'm having a problem that the BRAM read output doesn't change, I've used BRAMS many times before (not 7-series so I may be missing something subtle) and am totally perplexed as to why it is doing this.
I filled the stack with values: 1, 2 ,3
When I then call pop successively the only value it reads out is 3 for each pop and read address (even after waiting for the one clock read delay). I have also tried with dual port rams and had the same issue, i'm sticking to single port as it simpler to try and workout what is going wrong!
I have verified the logic behavior using an array based ram which has the correct behavior. For verification I also checked the logic from this source: http://vhdlguru.blogspot.co.uk/2011/01/implementation-of-stack-in-vhdl.html.
So the issue appears to be with the BRAM, either it is not reading properly or for some reason it is writing the value 3 to all previous memory address which makes no sense as each data item is synced with a write signal and correct address.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.numeric_std.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
-- Stack implementation for 32 bit data items using BRAM componenets
entity stack_32_BRAM is
generic( ADDR : integer :=32);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
en : in STD_LOGIC;
push_pop : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR (31 downto 0);
data_out : out STD_LOGIC_VECTOR (31 downto 0));
end stack_32_BRAM;
architecture Behavioral of stack_32_BRAM is
COMPONENT BRAM_32_1K
PORT (
clka : IN STD_LOGIC;
rsta : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
clkb : IN STD_LOGIC;
rstb : IN STD_LOGIC;
web : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addrb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dinb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT BRAM_32_1K_SP
PORT (
clka : IN STD_LOGIC;
rsta : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
--The read ptr is a function of the write ptr
signal stack_ptr_read, stack_ptr_write : std_logic_vector(ADDR-1 downto 0) := (others =>'0');
signal full, empty : std_logic := '0';
signal WEA : std_logic_vector(3 downto 0) :=(others=>'0'); -- 4-bit input: A port write enable
signal addra, addrb, dinb, doutb, dina, douta : std_logic_vector(31 downto 0) := (others => '0');
signal rsta, rstb :std_logic := '0' ;
type ram is array (4 downto -2) of std_logic_vector(31 downto 0) ;
signal mem : ram :=(others=>(others=>'0'));
begin
---STACK LOGIC ---
PUSH : process (clk, push_pop, en, full, empty)
begin
if(clk'event and clk='1') then
WEA <= "0000";
if(en='1' and push_pop = '1' and full = '0') then
mem(to_integer(unsigned(stack_ptr_write))) <= data_in;
WEA <= "1111";
dina <= data_in ;
ADDRA <= stack_ptr_write;
stack_ptr_write <= stack_ptr_write + 1;
elsif(en='1' and push_pop = '0' and empty = '0') then
data_out <= douta ;--
doutb <= mem(to_integer(unsigned(stack_ptr_write - 1)));
ADDRA <= stack_ptr_write - 1;
stack_ptr_write <= stack_ptr_write - 1;
end if;
end if;
end process;
BRAM_SP : BRAM_32_1K_SP
PORT MAP (
clka => clk,
rsta => rsta,
wea => wea,
addra => addra,
dina => dina,
douta => douta
);
end Behavioral;
Many thanks
Sam
The solution entails several things:
1) You have to explicitly reset the signals with the rst port in every process. Initializing them in their declaration just doesn't cut it.
The process' code with a proper reset and sensitivity list should then look like this:
PUSH : process (rst, clk)
begin
if (rst = '1') then --supposing active-high async. reset
WEA <= (others => '0');
ADDRA <= (others => '0');
dina <= (others => '0');
data_out <= (others => '0');
full <= '0';
empty <= '0';
stack_ptr_write <= (others => '0');
elsif(clk'event and clk='1') then
--your code
2) I understand you have several layers/tries of code here in the same place. This is messy to read. I see you are using a "mem" to hold your example (so that WEA, ADDRA, dina, etc are ignorable), but when you get back to BRAM_32_1K_SP remember to check it has 32 bits addresses which, coupled with 32 bits data, mean that you have a 32 * 2**32 bits ram... that is around 128 Gbits, typo I guess.
However, to make a clearer question you should leave only the code pertaining to the memory solution you're having a problem with.
3) your code does include some typos that you should fix, like assigning "doutb" in the process, whereas I guess you wanted to assign data_out instead:
data_out <= mem(to_integer(unsigned(stack_ptr_write - 1)));
And this is the reason why you don't see what you want at the output.