How to create port map that maps a single signal to 1 bit of a std_logic_vector? - vhdl

I am designing some hardware using VHDL. My design requires the use of a 12-bit ripple counter that will utimately get connected as shown in the schematic screenshot below.
I found an existing entity & architecture for a ripple counter from online that I have decided should be suitable for my design. Here it is, in case it is useful in helping answer my question.
entity ripple_counter is
generic (
n : integer := 12
);
port (
clk : in std_logic;
clear : in std_logic;
dout : out std_logic_vector(n-1 downto 0)
);
end ripple_counter;
architecture behavioral of ripple_counter is
signal clk_i, q_i : std_logic_vector(n-1 downto 0);
begin
clk_i(0) <= clk;
clk_i(n-1 downto 1) <= q_i(n-2 downto 0);
gen_cnt: for i in 0 to n-1 generate
dff: process(clear, clk_i)
begin
if (clear = '1') then
q_i(i) <= '1';
elsif (clk_i(i)'event and clk_i(i) = '1') then
q_i(i) <= not q_i(i);
end if;
end process dff;
end generate;
dout <= not q_i;
end behavioral;
One will see that the ripple counter entity uses a n-bit (12-bit in this case) std_logic_vector for it's output. But, only two of the Q* outputs get connected. The ripple counter's component and port map declarations have been created as follows. Note that u22d_out, u21b_out and, u26_q12_out are all signals that have been defined in the same structural architecture as the ripple counter's component and port map. Also, q10 is an output of the system.
component ripple_counter is
generic (
n : integer := 12
);
port (
clk : in std_logic;
clear : in std_logic;
dout : out std_logic_vector(n-1 downto 0)
);
end component;
u26: ripple_counter port map (
clk => u22d_out,
clear => u21b_out,
dout(11) => u26_q12_out,
dout(9) => q10
);
When I attempt to run my design I get the following errors...
Error: [42972]: "c:/somefilepath/somefilename.vhd", line 493: Incomplete sub-element association for formal dout
Error: [42604]: "c:/somefilepath/somefilename.vhd", line 489: Port and Port Map does not match
Error: [40008]: HDL analysis failed.
Line 493 is the line that reads dout(9) => q10.
Line 489 is the line that reads u26: ripple_counter port map.
I am unsure if this is a syntax error or if it is a functional issue. How can I map specific bits of a vector to a single signal?

As suggested by Brian D in the comments...the port map association was incomplete. Here is an updated version of the port map.
u26: ripple_counter port map (
clk => u22d_out,
clear => u21b_out,
dout(11) => u26_q12_out,
dout(10) => open,
dout(9) => q10,
dout(8 downto 0) => open
);

Related

VHDL No drivers exist on out port

I am doing my first project in VHDL, I try to implement 8-bit barrel shifter using mux.
This is code for one block (8 mux in chain):
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.sample_package.all;
-------------------------------------
ENTITY Shifter IS
GENERIC (n : INTEGER );
PORT ( x,y: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
redB: IN Integer;
out_m: OUT STD_LOGIC_VECTOR(n-1 downto 0));
END Shifter;
--------------------------------------------------------------
ARCHITECTURE dfl OF Shifter IS
SIGNAL sm : STD_LOGIC;
SIGNAL what_b : STD_LOGIC;
BEGIN
--redB in the number of the red block in the diagram
--The first mux port map is the same for all three blocks
sm <= y(redB);
first : MUX port map(
a => x(0),
b => '0',
s0 => sm,
y => out_m(0)
);
b0: if redB=0 generate --First block - only the first mux has b=0
rest : for i in 1 to n-1 generate
chain : MUX port map(
a => x(i),
b => x(i-1),
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
b1: if redB=1 generate
rest : for i in 1 to n-1 generate
what_b <= '0' when i=1 else --Second block - 2 first mux has b=0
x(i-2);
chain : MUX port map(
a => x(i),
b => what_b,
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
b2: if redB=2 generate
rest : for i in 1 to n-1 generate
what_b <= '0' when i=1 or i=2 or i=3 else --Third block - 4 first mux has b=0
x(i-4);
chain : MUX port map(
a => x(i),
b => what_b,
s0 => sm,
y => out_m(i)
);
end generate;
end generate;
END dfl;
In this is the code for changing 3 shifters:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.sample_package.all;
-------------------------------------
ENTITY Barrel IS
GENERIC (n : INTEGER);
PORT ( x,y: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
out_shifter0,out_shifter1,out_shifter2: OUT STD_LOGIC_VECTOR(n-1 downto 0));
END Barrel;
--------------------------------------------------------------
ARCHITECTURE dfl OF Barrel IS
SIGNAL temp_out0 : std_logic_vector(n-1 DOWNTO 0);
SIGNAL temp_out1 : std_logic_vector(n-1 DOWNTO 0);
SIGNAL temp_out2 : std_logic_vector(n-1 DOWNTO 0);
BEGIN
y0: Shifter GENERIC MAP(n) port map (x=>x,y=>y,redB=>0,out_m=>temp_out0);
out_shifter0 <= temp_out0;
y1: Shifter GENERIC MAP(n) port map (x=>temp_out0,y=>y,redB=>1,out_m=>temp_out1);
out_shifter1 <= temp_out1;
y2: Shifter GENERIC MAP(n) port map (x=>temp_out1,y=>y,redB=>2,out_m=>temp_out2);
out_shifter2 <= temp_out2;
END dfl;
All the files are compiling, but when I try to run a simulation I get this warning:
# ** Warning: (vsim-8684) No drivers exist on out port /tb/L0/y1/out_m(7 downto 1), and its initial value is not used.
#
# Therefore, simulation behavior may occur that is not in compliance with
#
# the VHDL standard as the initial values come from the base signal /tb/L0/temp_out1(7 downto 1).
I am using ModelSim.
Anyone got any idea of what could be the problem?
Thanks!
You have done a generate with a signal, and compared its value to something. Integers initialise to -2^31, so none of the generate blocks exist because the values you have assigned externally do not get assigned until after the simulation is started, but the generates get created during elaboration (before the simulation starts) using the initial value of redB. Hence no drivers for out_m. Instead of using a signal in the generate condition, use generics instead, as their values are fixed and assigned during elaboration.

Need help about variable declaration in VHDL

I am studying VHDL for my degree and I was asked to fix the error in this code, but after many tries I cannot manage to make it run. The compiler returns "Mem_Addr is used but not declared", highlighting the line that I mention below. I cannot manage to declare Mem_Addr properly.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.ALL;
ENTITY Ifetch IS
PORT( SIGNAL Instruction : OUT STD_LOGIC_VECTOR( 31 DOWNTO 0 );
SIGNAL PC_plus_4_out : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 );
SIGNAL Add_result : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 );
SIGNAL Branch : IN STD_LOGIC;
SIGNAL Zero : IN STD_LOGIC;
SIGNAL PC_out : OUT STD_LOGIC_VECTOR( 9 DOWNTO 0 );
SIGNAL clock, reset : IN STD_LOGIC);
END Ifetch;
ARCHITECTURE behavior OF Ifetch IS
SIGNAL PC, PC_plus_4 : STD_LOGIC_VECTOR( 9 DOWNTO 0 );
SIGNAL next_PC : STD_LOGIC_VECTOR( 7 DOWNTO 0 );
BEGIN
--ROM for Instruction Memory
data_memory: altsyncram
GENERIC MAP (
operation_mode => "ROM",
width_a => 32,
widthad_a => 8,
lpm_type => "altsyncram",
outdata_reg_a => "UNREGISTERED",
-- Reads in mif file for initial data memory values
init_file => "program.mif",
intended_device_family => "Cyclone")
-- Fetch next instruction from memory using PC
PORT MAP (
clock0 => clock,
-- ERROR HERE
address_a => Mem_Addr,
--
q_a => Instruction
);
-- Instructions always start on a word address - not byte
PC(1 DOWNTO 0) <= "00";
-- copy output signals - allows read inside module
PC_out <= PC;
PC_plus_4_out <= PC_plus_4;
-- send word address to inst. memory address register
Mem_Addr <= Next_PC;
-- Adder to increment PC by 4
PC_plus_4( 9 DOWNTO 2 ) <= PC( 9 DOWNTO 2 ) + 1;
PC_plus_4( 1 DOWNTO 0 ) <= "00";
-- Mux to select Branch Address or PC + 4
Next_PC <= X"00" WHEN Reset = '1' ELSE
Add_result WHEN ( ( Branch = '1' ) AND ( Zero = '1' ) )
ELSE PC_plus_4( 9 DOWNTO 2 );
-- Store PC in register and load next PC on clock edge
PROCESS
BEGIN
WAIT UNTIL ( clock'EVENT ) AND ( clock = '1' );
IF reset = '1' THEN
PC <= "0000000000" ;
ELSE
PC( 9 DOWNTO 2 ) <= Next_PC;
END IF;
END PROCESS;
END behavior;
You're connecting the address port of the ram to a signal called mem_addr - only that signal does not exist because you didnt declare it.
You need something like this next to the other signals:
signal Mem_Addr : std_logic_vector(7 downto 0);
First of all, in the Entity declaration the attributes 'SIGNAL' are unnecessary. Regarding your problem, you did not declare Mem_Addr signal. You have to declare it in the architecture :
architecture BEHAVIOR of ...
begin
signal Mem_Addr : std_logic_vector(X downto 0);
Make sure to match X to the length-1 of the signal you connect it to (address_a)
Also, you have to drive the Mem_Addr signal with some signal carrying address values. Otherwise this signal will have undefined value, or be equal to the default value and will not impact the data memory.
So to fix this issue you have to find out if any signal in the Entity carries the address that you want to pass to the altsyncram memory or find out how to determine it based on the input signals of your component.

Writing a code for a CRC using D-FlipFlop in VHDL

I'm learning VHDL for a university project. The goal is to write a CRC circuit given a certain polynomial. I found online solution that uses register but I wanted to do it by using actual D-FlipFlop.
So I created the D-FlipFlop and put in my main file several instances of them using generate to be more flexible and be able to add or remove flipflop easily.
library IEEE;
use IEEE.std_logic_1164.all;
entity LFSR is
generic (NBit : positive := 8);
port(
clk :in std_logic;
reset :in std_logic;
din :in std_logic;
dout :out std_logic_vector(Nbit-1 downto 0)
);
end LFSR;
architecture rtl of LFSR is
component DFC
port(
clk :in std_logic;
reset :in std_logic;
d :in std_logic;
crc :out std_logic;
q :out std_logic
);
end component DFC;
signal q_s : std_logic_vector (NBit-1 downto 0):= (others => '0');
signal crc_t : std_logic_vector (NBit-1 downto 0):= (others => '0'); --registro temporaneo su cui fare le operazioni
signal int_0 :std_logic := '0';
signal int_2 :std_logic := '0';
signal int_4 :std_logic := '0';
signal int_8 :std_logic := '0';
begin
int_0<= din xor q_s(7);
int_2<= q_s(1) xor q_s(7);
int_4<= q_s(3) xor q_s(7);
GEN: for i in 0 to Nbit-1 generate
FIRST: if i=0 generate
FF1: DFC port map (
clk => clk,
reset => reset,
d => int_0,
crc => crc_t(i), --funziona benissimo se metto dout(i)
q => q_s(i)
);
end generate FIRST;
THIRD: if i=2 generate
FF2: DFC port map (
clk => clk,
reset => reset,
d => int_2,
crc => crc_t(i),
q => q_s(i)
);
end generate THIRD;
FIFTH: if i=4 generate
FF4: DFC port map (
clk => clk,
reset => reset,
d => int_4,
crc => crc_t(i),
q => q_s(i)
);
end generate FIFTH;
INTERNAL: if i>0 and i<Nbit-1 and i/= 2 and i/=4 generate
FFI: DFC port map (
clk => clk,
reset => reset,
d => q_s(i-1),
crc => crc_t(i),
q => q_s(i)
);
end generate INTERNAL;
LAST: if i=Nbit-1 generate
FFN: DFC port map (
clk => clk,
reset => reset,
d => q_s(i-1),
crc => crc_t(i),
q => q_s(i)
);
end generate LAST;
end generate GEN;
variable t : natural := 0;
begin
if(rising_edge(clk)) then
t:= t+1;
if t=24 then
dout <= crc_t;
end if;
end if;
end process;
end rtl;
Of course on line 35, where I put "d => din xor q_s(Nbit-1)", the compiler gives me an error. How can I obtain the result I want to get?
I tried putting intermediary signal to pass this problem, but I can't understand why this is not working as expected.
This is the code of the DFC component:
library IEEE;
use IEEE.std_logic_1164.all;
entity DFC is
port(
clk :in std_logic;
reset :in std_logic;
d :in std_logic;
crc :out std_logic;
q :out std_logic
);
end DFC;
architecture rtl of DFC is
begin
process(clk, reset, d)
begin
if(reset = '1')then
q <= '0';
crc<= '0';
elsif (clk'event and clk='1') then
q <= d;
crc <= d;
end if;
end process;
end rtl;
Thanks all for the aswers.
Gabriele.
Edit: I added all the LFSR code and the DFC code.
Your question is incomplete because it does not have a minimal reproductible code. In other word, it is hard to help you.
Prior to VHDL-2008:
You cannot perform such action : d => din xor q_s(Nbit-1) because this line is seen as an operation and that is not possible in an instantiation of an entity or a component.
(like in this post for example: https://electronics.stackexchange.com/questions/184893/warning-actual-for-formal-port-a-is-neither-a-static-name-nor-a-globally-stati)
However, there is a way to work around that, you have to create a new signal
Notice that when you use your code, the error should be something like: Actual for formal port a is neither a static name nor a globally static expression
With VHDL-2008:
If look in the norm: http://www.fis.agh.edu.pl/~skoczen/hdl/ieee_std/ieee1076-2008.pdf
You can find on paragraph 6.5.6.3 Port clauses:
If a formal port of mode in is associated with an expression that is not globally static (see 9.4.1) and the
formal is of an unconstrained or partially constrained composite type requiring determination of index
ranges from the actual according to the rules of 5.3.2.2, then the expression shall be one of the following:
The name of an object whose subtype is globally static
An indexed name whose prefix is one of the members of this list
A slice name whose prefix is one of the members of this list and whose discrete range is a globally static discrete range
An aggregate, provided all choices are locally static and all expressions in element associations are expressions described in this list
A function call whose return type mark denotes a globally static subtype
A qualified expression or type conversion whose type mark denotes a globally static subtype
An expression described in this list and enclosed in parentheses
In other word, in VHDL-2008, the code you provided should work.
About your initialization problem, it is unclear, what signals/varibles are not initialized ? The best you can do is, if your first question is well answered by this post, then accept it has a solution or edit your question for more clarity. Then ask an other question in an other thread about the initialization problem. You can also post your question on Electronics Stackexchange

Weird behaviour in vhdl average using Microsemi FPGA

Good Afternoon, I am working on some code of averaging with a sliding window using VHDL language.
The problem is that the accumulator takes sometimes wrong values. (generally after restart)
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.std_logic_unsigned.all;
entity cc_rssi_avr is
port (
nrst : in std_logic;
clk : in std_logic; --
ena : in std_logic;
data_in : in std_logic_vector(9 downto 0);
data_out : out std_logic_vector(9 downto 0)
);
end cc_rssi_avr;
architecture rtl of cc_rssi_avr is
constant buffer_size : natural :=8;
type MEM is array(0 to buffer_size-1) of std_logic_vector(9 downto 0);
signal shift_LT : MEM:=(others =>(others=>'0'));
signal sum_val:std_logic_vector(12 downto 0);
begin
--shift input data at every clock edge
process(clk,nrst)
begin
if nrst='0' then
shift_LT <= (others => (others => '0'));
sum_val <= (others=>'0');
elsif clk'event and clk='1' then
if ena = '0' then
shift_LT<=(others=>(others=>'0'));
sum_val<=(others=>'0');
else
shift_LT(0) <= data_in;
shift_LT(1 to buffer_size-1) <= shift_LT(0 to buffer_size-2);
sum_val <= sum_val + ("000"&data_in) - ("000"&shift_LT(buffer_size-1));
end if;
end if;
end process;
data_out<=sum_val(sum_val'high downto 3);
end rtl;
The problem is somehow, sum_val adds a value without subtraction or subtracts without addition, in a way that if the input returns to 0, the output returns to 7850 or a random value but not zero.
The design is running # 20 MHz (FPGA : Microsemi Smartfusion M2S050), and consists on an ADC driven by FPGA clock, and its output is routed to the FPGA pins so the samples are processed with this module in order to compute the average on 8 samples.
One last information that might be useful : FPGA is 92.6% Occupied (4LUT).
Can anyone provide some help.
Thanks

How to reuse an entity to work with different components

I'm reasonably new to vhdl and wondering what the best way is to manage the following situation / pattern:
Say I have an entity A whose architecture instantiates a component B. I would then like to reuse A but this time instantiate a component C in the place of B. C has a completely different functionality to B. B and C may have different sized ports, however the functionality of A is such that it can handle the different port sizes, using, say, generics and generate statements. Essentially A is like a container for either component B, C or maybe D, E, F etc. It maybe performs some logic/buffering on the inputs and outputs of B, C etc. in a way that is common for all these components.
I have read about configurations and my understanding is that I can instantiate a component in A (call it Z), and then link it's entity to different architectures using configurations. It seems not many people use this feature of vhdl.
Are configurations the right way to go for this situation?
Ideally, I would like all of the parameters in the design to depend ultimately on the architecture chosen for Z so that the architecture dictates the port sizes of the entity its linked to (Z), and in turn the port sizes of Z dictate the parameters of A and finally these parameters dictate the port sizes of A. Is this possible?
(I am using 'parameterisation' in the general sense to mean a way of configuring a design. Generics, packages, 'range attributes etc would all be examples of parameterisation)
A pseudocode example of what I mean is below. The values in capitals should depend on the architecture chosen for Z.
entity A is
port
(
clk : in std_logic;
reset : in std_logic;
inputs : in std_logic_vector(SOME_WIDTH_A_IN - 1 downto 0);
outputs : out std_logic_vector(SOME_WIDTH_A_OUT - 1 downto 0);
);
end A;
architecture A_arch of A is
component Z
port
(
clock : in std_logic;
inputs : std_logic_vector(SOME_WIDTH_Z_IN - 1 downto 0);
ouputs : std_logic_vector(SOME_WIDTH_Z_OUT - 1 downto 0)
);
end component;
begin
for i in 1 to SOME_VALUE generate
-- whatever logic/buffering we want to perform on the inputs
end generate;
for i in 1 to SOME_VALUE generate
-- whatever logic/buffering we want to perform on the outputs
end generate;
instance: Z
port map(
clock => clk,
inputs => --output of logic/buffering above
outputs => -- input of logic/buffering above
);
end A_arch;
I may be thinking about this the wrong way - Essentially I would like to avoid having to copy/paste the 'container' entity A to work with different components B, C etc. What is the best way to do this?
It seems that you want your components B,C,D, etc... to do exactly the same except for different port sizes. The best approach to do this is with GENERIC. Let's say your other entity (let's call it INNER_ENTITY) is configurable n-bit wide double flip flop (can be used to resolve metastability).
Here is the example code for OUTER_ENTITY and INNER_ENTITY:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity OUTER_ENTITY is
port (
CLK : in std_logic;
RST : in std_logic;
PORT_A : in std_logic_vector(6 downto 0);
PORT_B : in std_logic_vector(13 downto 0);
SUM_A_B : out std_logic_vector(13 downto 0)
);
end entity;
architecture RTL_OUTER_ENTITY of OUTER_ENTITY is
signal PORT_A_INNER : std_logic_vector(6 downto 0);
signal PORT_B_INNER : std_logic_vector(13 downto 0);
component INNER_ENTITY
generic (PORT_SIZE : integer);
port (
CLK : in std_logic;
RST : in std_logic;
PORT_IN : in std_logic_vector(PORT_SIZE - 1 downto 0);
PORT_OUT : out std_logic_vector(PORT_SIZE - 1 downto 0);
);
end component INNER_ENTITY;
begin
SUM_A_B <= PORT_A_INNER + PORT_B_INNER;
INNER_7_BIT : INNER_ENTITY
generic map (PORT_SIZE => 7)
port map (
CLK => CLK,
RST => RST,
PORT_IN => PORT_A,
PORT_OUT => PORT_A_INNER
);
INNER_14_BIT : INNER_ENTITY
generic map (PORT_SIZE => 14)
port map (
CLK => CLK,
RST => RST,
PORT_IN => PORT_B,
PORT_OUT => PORT_B_INNER
);
end RTL_OUTER_ENTITY;
entity INNER_ENTITY
generic (PORT_SIZE : integer);
port (
CLK : in std_logic;
RST : in std_logic;
PORT_IN : in std_logic_vector(PORT_SIZE - 1 downto 0);
PORT_OUT : out std_logic_vector(PORT_SIZE - 1 downto 0);
);
end entity;
architecture RTL_INNER_ENTITY of INNER_ENTITY is
signal PORT_X : std_logic_vector(PORT_SIZE - 1 downto 0);
begin
process(CLK, RST)
begin
if RST = '1' then
PORT_OUT <= (OTHERS => '0');
PORT_X <= (OTHERS => '0');
elsif rising_edge(CLK) then
PORT_OUT <= PORT_X;
PORT_X <= PORT_IN;
end if;
end process;
end RTL_INNER_ENTITY;
Please note that I did not compile this code so it might have some minor syntax errors but it should give you an overview to how GENERICs might be used to do what you want.

Resources