Need help about variable declaration in VHDL - 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.

Related

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

vhdl equivalent for initial block in verilog

I am trying to convert some Verilog code to VHDL. I have difficulties to translate initial block in Verilog to VHDL properly.
As far as I know, the initial block corresponds to the process statement without a sensitivity list but we have to add a "wait" statement before the "end process".I tried it but it did not work. I tried some other methods too (using exit clause, conditional clause ( wait until), "for- generate" without process, etc) but none was successful.
Here is the Verilog code I want to convert, and it works properly
module MyRAM #(parameter DATA_WIDTH=24, parameter ADDR_WIDTH=10)
(
input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] read_addr, write_addr,
input we, clk,
output reg [(DATA_WIDTH-1):0] q
);
// Declare the RAM variable
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
initial
begin : INIT
integer i;
for(i = 1; i < ((2**ADDR_WIDTH)-1); i = i+1) begin
if (i == 132) ram[i] = 24'h550000;
else if (i == 133) ram[i] = 24'h005500;
else if (i == 134) ram[i] = 24'h000055;
else ram[i] = 24'h000000;
end
//*/
end
always # (negedge clk)
begin
// Write
if (we)
ram[write_addr] <= data;
q <= ram[read_addr];
end
endmodule
and this is the VHDL code I have written so far:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MyRAM is
generic
(DATA_WIDTH: integer;
ADDR_WIDTH: integer);
port
(
data :in std_logic_vector ((DATA_WIDTH-1) downto 0);
read_addr :in std_logic_vector((ADDR_WIDTH-1) downto 0);
write_addr :in std_logic_vector(( DATA_WIDTH-1) downto 0);
we :in std_logic;
clk :in std_logic;
q :out std_logic_vector( 23 downto 0)
);
end MyRAM;
architecture behavioral of MyRAM is
constant case1:std_logic_vector(23 downto 0):=
(16=>'1',18=>'1',20=>'1',22=>'1',others=>'0');
constant case2:std_logic_vector(23 downto 0):=
(8=>'1',10=>'1',12=>'1',14=>'1',others=>'0');
constant case3:std_logic_vector(23 downto 0):=
(0=>'1',2=>'1',4=>'1',6=>'1',others=>'0');
type ram is array ( 0 to (2**ADDR_WIDTH-1)) of
std_logic_vector((DATA_WIDTH-1) downto 0);
shared variable origram:ram;
signal s_q: std_logic_vector(23 downto 0);
begin
process
begin
for ii in 1 to (2**ADDR_WIDTH-1) loop
if (ii = 132) then
origram(ii) := case1;
elsif (ii = 133) then
origram(ii) := case2;
elsif (ii = 134) then
origram(ii) := case3;
else
origram(ii) :=(others=>'0');
end if;
end loop;
wait;
end process;
process (clk)
begin
if falling_edge(clk) then
if (we ='1') then
origram(to_integer(unsigned(write_addr))) := data;
s_q <= origram(to_integer(unsigned(read_addr)));
end if;
end if;
end process;
q<=s_q;
end behavioral;
And this is the error message:
Error (10533): VHDL Wait Statement error at MyRAM.vhd(88): Wait Statement must contain condition clause with UNTIL keyword
I do not have much experience in these languages, so I would appreciate any kind of help
The answer is both yes and no. While yes, you can do pretty much what you can do in an initial block in a process, in your situation the answer is you are actually initialising a signal. For this you need to use a function, and set the initial value:
type ram is array ( 0 to (2**ADDR_WIDTH-1)) of std_logic_vector((DATA_WIDTH-1) downto 0);
function init_ram return ram is
variable r : ram;
begin
-- set the contents of the ram
end function init_ram;
shared variable origram:ram := init_ram;
Processes with wait at the end are only for simulation (which would mimic an initial block in verilog used for testbench stimulus)
Note: from VHDL 2002, using a shared variable like this is illegal as it should be a protected type (which is not synthesisable currently). The only reason you might want a shared variable (rather than a signal) to infer a ram is to get write-before-read behaviour in a RAM. It is very annoying most of the Xilinx Inference examples use a shared variable. Switching your code to VHDL2008 will throw the error mentioned above.
A process with a ram variable instead of a shared variable can provide an initial value as well:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MyRAM is
generic (
DATA_WIDTH: integer;
ADDR_WIDTH: integer
);
port (
data: in std_logic_vector (DATA_WIDTH - 1 downto 0);
read_addr: in std_logic_vector (ADDR_WIDTH - 1 downto 0);
write_addr: in std_logic_vector (DATA_WIDTH - 1 downto 0);
we: in std_logic;
clk: in std_logic;
q: out std_logic_vector (DATA_WIDTH - 1 downto 0)
);
end entity MyRAM;
architecture behavioral of MyRAM is
constant case1: std_logic_vector(23 downto 0) :=
(16 => '1', 18 => '1', 20 => '1', 22 => '1', others => '0');
constant case2: std_logic_vector(23 downto 0) :=
( 8 => '1', 10 => '1', 12 => '1', 14 => '1', others => '0');
constant case3: std_logic_vector(23 downto 0) :=
( 0 => '1', 2 => '1', 4 => '1', 6 => '1', others => '0');
type ram is array ( 0 to 2 ** ADDR_WIDTH - 1) of
std_logic_vector(DATA_WIDTH - 1 downto 0);
begin
MY_RAM:
process (clk)
function init_origram return ram is
variable ramval: ram;
begin
for ii in ram'left to ram'right loop
if ii = 132 then -- note the presumption ram has at least 135 elements
ramval(ii) := case1;
elsif ii = 133 then
ramval(ii) := case2;
elsif ii = 134 then
ramval(ii) := case3;
else
ramval(ii) := (others => '0');
end if;
end loop;
return ramval;
end function;
variable origram: ram := init_origram;
begin
if falling_edge(clk) then
if we = '1' then -- write before read
origram(to_integer(unsigned(write_addr))) := data;
end if;
q <= origram(to_integer(unsigned(read_addr)));
end if;
end process;
end architecture behavioral;
This would be useful in IEEE Std 1076-2000, -2002 and -2008 compliant tool chains where shared variables are required to be protected types as well as earlier standard revisions.
IEEE Std 1076-2008
9.3.3 Aggregates
9.3.3.1 General:
element_association ::=
[ choices => ] expression
choices ::= choice { | choice }
You can also use the separator '|` to provide multiple values for choices:
constant case1: std_logic_vector(23 downto 0) :=
-- (16 => '1', 18 => '1', 20 => '1', 22 => '1', others => '0');
(16 | 18 | 20 | 22 => '1', others => '0');
or even provide a base specifier X bit string for a hexidecimal value here (15.8 Bit string literals).

Multiply Accumulate Unit

I have a MAC unit for a transport triggered architecture processor, but for some reason. the multiply-accumulate part isn't working. I tested it separately and it worked, but when simulated out_reg_int is always 0 even though op_a and op_b are the correct values and I have included Numeric_STD.
-- These are just for the question
num_in_reg := 2;
num_reg := 4;
data_size := 71;
data_width := 64;
SIGNAL op_a, op_b : SIGNED(data_width-1 DOWNTO 0);
Signal out_reg_int, out_reg_out_int : SIGNED((data_width*2)-1 DOWNTO 0);
TYPE bus_array3 IS ARRAY (num_reg-1 DOWNTO num_in_reg) OF Signed(data_width-1 DOWNTO 0);
SIGNAL out_reg_in: bus_array3; -- for output register inputs
SIGNAL result: bus_array3; -- for results
op_a <= SIGNED(reg_out(0)(data_width-1 DOWNTO 0)); -- operand A
op_b <= SIGNED(reg_out(1)(data_width-1 DOWNTO 0)); -- operand B (trigger register)
-- Multiply Accumulate Operation
out_reg_int <= (op_a * op_b) + out_reg_out_int; -- multiply operands and add to current result
out_reg_out_int <= result(3) & result(2); -- combining the output registers lower and higher parts
out_reg_in(2) <= out_reg_int(data_width-1 downto 0); -- lower part of the result
out_reg_in(3) <= out_reg_int((data_width*2)-1 downto data_width); -- upper part of the result
------------------------------------------------------
-- Basically a register for pre place and route simulation.
------------------------------------------------------
result_regs: FOR J IN num_in_reg TO num_reg-1 GENERATE
Razor_result : entity work.Razor(Behavioral)
Generic Map (data_size => data_width)
Port Map (clk => CLK,
rst => Test_rst,
data => std_logic_vector(out_reg_in(J)),
wen => out_reg_en(J),
signed(data_out) => result(J),
error => Razor_error_int(J));
End Generate;
In the Testbench op_a is x64 and op_b is x100 and out_reg_int, out_reg_in and out_reg_out_int are all 0.
The full code for the unit is This :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.DigEng.All;
entity MAC is
Generic (data_size : INTEGER := 71; -- size of data
num_in_reg: INTEGER := 2; -- number of input registers
data_width: INTEGER := 64; --size of data minus parity bits
num_reg : INTEGER := 4);-- number of input and output registers
PORT (CLK : IN STD_LOGIC;
rst : IN STD_LOGIC; -- reset
en_all : IN STD_LOGIC; -- enable for all sequential elements
test_mode : IN STD_LOGIC; -- Hamming Fault Tolerance Testing
reg_input : IN STD_LOGIC_VECTOR(data_size-1 downto 0);
reg_output : OUT STD_LOGIC_VECTOR(data_size-1 downto 0);
error_en : IN STD_LOGIC; -- Hamming Error enable
we_regs : IN STD_LOGIC_VECTOR(num_reg-1 DOWNTO 0); -- registers write enable
re_regs : IN STD_LOGIC_VECTOR(num_reg-1 DOWNTO 0); -- registers read enable
Razor_error : OUT STD_LOGIC; -- Timing error occured
HW_Error : OUT STD_LOGIC); -- Error signal for FU replacement
end MAC;
architecture Behavioral of MAC is
---------------------------
-- Components declaration
---------------------------
-- Declaring D flipflop
COMPONENT d_ff IS
PORT(clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
en : IN STD_LOGIC;
data: IN STD_LOGIC;
q : OUT STD_LOGIC);
END COMPONENT;
--------------------
-- Internal signals
--------------------
-- Type declaration to array of buses for Outputs of all registers
TYPE bus_array IS ARRAY (num_reg-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_size-1 DOWNTO 0);
SIGNAL reg_out: bus_array; -- for registers outputs
TYPE bus_array4 IS ARRAY (num_in_reg-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_size-1 DOWNTO 0);
SIGNAL reg_input_int: bus_array4; -- for registers outputs
TYPE bus_array3 IS ARRAY (num_reg-1 DOWNTO num_in_reg) OF Signed(data_width-1 DOWNTO 0);
SIGNAL out_reg_in: bus_array3; -- for output register inputs
SIGNAL result: bus_array3; -- for results
TYPE bus_array5 IS ARRAY (num_reg-1 DOWNTO num_in_reg) OF STD_LOGIC_VECTOR(data_size-1 DOWNTO 0);
Signal post_op_hamming_in : bus_array5;
-- Input registers enables
TYPE reg_en IS ARRAY (num_in_reg-1 DOWNTO 0) OF STD_LOGIC;
SIGNAL in_reg_en: reg_en;
-- Output registers enables
TYPE reg_en2 IS ARRAY (num_reg-1 DOWNTO num_in_reg) OF STD_LOGIC;
SIGNAL out_reg_en: reg_en2;
-- Oprand A, operand B and operation trigger
SIGNAL op_a, op_b : SIGNED(data_width-1 DOWNTO 0);
Signal test_Input1, test_Input2, test_Output_High, test_Output_low : STD_LOGIC_VECTOR(data_width-1 DOWNTO 0);
SIGNAL t_op, test_rst, test_en, test_rst_int, test_en_delayed : STD_LOGIC; -- enable for the output registers
Signal out_reg_int, out_reg_out_int : SIGNED((data_width*2)-1 DOWNTO 0);
SIGNAL In_Hamming_out : STD_LOGIC_VECTOR(data_size-1 DOWNTO 0);
Signal Razor_error_int : STD_LOGIC_VECTOR(Num_reg-1 downto 0);
BEGIN
-----------------------------------------------
-- Logic for the sequential elements enable
-----------------------------------------------
-- For input registers
input_regs_en: FOR H IN 0 TO num_in_reg-1 GENERATE
in_reg_en(H) <= (we_regs(H) AND en_all) OR Test_en;
END GENERATE;
-- Instantiate D flipflop
Inst_d_ff: d_ff
PORT MAP(clk => clk ,
rst => rst,
en => en_all, -- delay the trigger signal for a clock cycle
data => we_regs(1), -- delayed reg(1) write enable is used as trigger
q => t_op);
-- For output registers
output_regs_en: FOR I IN num_in_reg TO num_reg-1 GENERATE
out_reg_en(I) <= (t_op AND we_regs(1) AND en_all) OR Test_en ;
END GENERATE;
-------------------------------------------------
-- Instantiate hamming module to check input data
-------------------------------------------------
In_Hamming_module: entity work.Hamming_Module(Behavioral)
Generic Map (data_size => data_size)
PORT MAP(Data_in => reg_input,
Data_out => In_Hamming_out,
Error_en => error_en,
Error_sig => OPEN);
--------------------------------------------------------
-- Razor Shadow Latch Unit for checking Timing on Input
--------------------------------------------------------
input_regs: FOR J IN 0 TO num_in_reg-1 GENERATE
Razor_In : entity work.Razor(Behavioral)
Generic Map (data_size => data_size)
Port Map (clk => CLK,
rst => rst,
data => reg_input_int(J),
wen => in_reg_en(J),
data_out => reg_out(J),
error => Razor_error_int(J));
END GENERATE;
------------------------------------------------------
-- Razor Shadow Latch Unit for checking Timing post OP
------------------------------------------------------
result_regs: FOR J IN num_in_reg TO num_reg-1 GENERATE
Razor_result : entity work.Razor(Behavioral)
Generic Map (data_size => data_width)
Port Map (clk => CLK,
rst => Test_rst,
data => std_logic_vector(out_reg_in(J)),
wen => out_reg_en(J),
signed(data_out) => result(J),
error => Razor_error_int(J));
End Generate;
------------------------------------------------------
-- Instantiate hamming module to recalculate
-- parity values after operations
------------------------------------------------------
hamming_post_ops: FOR J IN num_in_reg TO num_reg-1 GENERATE
post_op_hamming_in(J) <= std_logic_vector(resize(result(J), data_size));
hamming_post_ops: entity work.Hamming_Module(Behavioral)
Generic Map (data_size => data_size)
PORT MAP(Data_in => post_op_hamming_in(J),
Data_out => reg_out(J),
Error_en => '0',
Error_sig => OPEN);
End Generate;
----------------------------
-- MAC Testing
----------------------------
Mac_Tester_Unit : entity work.MAC_Tester(Behavioral)
Generic Map(data_size => data_size, -- size of data
num_in_reg => num_in_reg, -- number of input registers
data_width => data_width, -- size of data minus parity bits
num_reg => num_reg) -- number of input and output registers)
Port Map(clk => clk,
en_all => Test_en,
Input_reg1 => test_Input1,
Input_reg2 => test_Input2,
Output_reg_lower => test_Output_High,
Output_reg_higher => test_Output_low,
rst => test_rst_int);
--------------------------------------------------------
-- Assigning the output of input registers to operands
--------------------------------------------------------
op_a <= SIGNED(reg_out(0)(data_width-1 DOWNTO 0)); -- operand A
op_b <= SIGNED(reg_out(1)(data_width-1 DOWNTO 0)); -- operand B (trigger register)
-- Multiply Accumulate Operation
out_reg_int <= (op_a * op_b) + out_reg_out_int; -- multiply operands and add to current result
out_reg_out_int <= result(3) & result(2); -- combining the output registers lower and higher parts
out_reg_in(2) <= out_reg_int(data_width-1 downto 0); -- lower part of the result
out_reg_in(3) <= out_reg_int((data_width*2)-1 downto data_width); -- upper part of the result
----------------------------------------------------------------
-- Tri-state buffer to output the chosen register output to the
-- central data bus
----------------------------------------------------------------
connections2: FOR J IN num_in_reg TO num_reg-1 GENERATE
reg_output <= reg_out(J) WHEN re_regs(J) = '1' ELSE (OTHERS => 'Z');
END GENERATE;
Razor_error <= Razor_error_int(0) OR Razor_error_int(1) OR Razor_error_int(2) OR Razor_error_int(3);
-----------------------------
-- Test Vector Assignment
-----------------------------
Test_en <= '1' When we_regs = "0000" AND re_regs = "0000" AND en_all = '1' AND error_en = '1' else '0';
Test_rst <= Test_rst_int When Test_en = '1' else rst;
reg_input_int(0)(data_width-1 downto 0) <= test_Input1 when Test_en = '1' else
In_Hamming_out(data_width-1 downto 0);
reg_input_int(1)(data_width-1 downto 0) <= test_Input2 when Test_en = '1' else
In_Hamming_out(data_width-1 downto 0);
------------------------------------------------------
-- Instantiate D flipflop for delaying output testing
------------------------------------------------------
Test_d_ff: d_ff
PORT MAP(clk => clk ,
rst => rst,
en => en_all,
data => Test_en, -- delay Test_en for 1 clock cycle for output check
q => Test_en_delayed);
HW_Error <= '0' When Test_en_delayed <= '0' OR (signed(test_Output_High) = result(3) AND signed(test_Output_low) = result(2)) else
'1';
end Behavioral;

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

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
);

VHDL Altera Qartus random data in unsigned register after (others => 0) + 1

I'm having trouble figuring out why I'm getting problems with my clock enable timer in a UART controller. The counter is cntR. It should start counting from zero after a condition is met, yet it starts at zero and then switches to a random number instead of incrementing 0 to 1. Here's the process code where something bad happens:
process(reset, clock)
begin
if reset = '1' then
cntR <= (others => '0');
elsif rising_edge(clock) then
if rcv_reg = r_idle and rxd = '1' then
cntR <= (others => '0');
else
if cntR = DIVVALUE then
cntR <= (others => '0');
else
cntR <= cntR + 1;
end if;
end if;
end if;
end process;
here are the declarations (probably not that important):
entity SART is
generic(
INCLK : natural := 50000000;
BAUDRATE : natural := 9600;
CNT_WIDTH : natural := 14
);
port(
clock : in std_logic;
reset : in std_logic;
send : in std_logic;
rxd : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_ready : out std_logic;
clear_to_send : out std_logic;
txd : out std_logic;
data_out : out std_logic_vector(7 downto 0)
);
end SART;
-- Receiver FSM states
type RCV_STATE_TYPE is (
r_idle,
r_start,
r_data1,r_data2,r_data3,r_data4,r_data5,r_data6,r_data7,r_data8,
r_stop1
);
signal rcv_reg, rcv_next : RCV_STATE_TYPE;
signal cntR : unsigned(CNT_WIDTH-1 downto 0);
This is what I get from Signal Tap:
For the record, I'm using Altera Quartus 13.0.0 and a DE0-Nano with a Cyclone IV FPGA.
Thank you in advance for your input.
I managed to fix this problem. It turns out, that I didn't have an SDC file in the project and hence the TimeQuest Timing Analyzer report stated that my maximum clock frequency is 10 times higher that when I had the SDC file attached. After writing an SDC file containing only clock declarations I got a maximum clock frequency of about 7 MHz from TimeQuest. I generated a PLL to get a 5 MHz frequency clock and now everything works flawlessly.

Resources