vivado: unused sequential element was removed - fpga

Let's suppose I have the following VHDL code that i'm synthesizing with Vivado:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity example1 is
port (
aclk :in std_logic;
aresetn :in std_logic;
ren :in std_logic;
wen :in std_logic;
count :out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of example1 is
signal reg_count :unsigned(7 downto 0);
signal sel :std_logic_vector(1 downto 0);
begin
count <= std_logic_vector(reg_count);
sel <= ren & wen;
process(aclk, aresetn)
begin
if (aresetn = '0') then
reg_count <= (others => '0');
elsif (rising_edge(aclk)) then
case sel is
when "00" => reg_count <= reg_count;
when "01" => reg_count <= (reg_count + 1);
when "10" => reg_count <= (reg_count - 1);
when "11" => reg_count <= reg_count;
when others => null;
end case;
end if;
end process;
end architecture;
How can I modify the above code to prevent the following synthesis warning messages:
[Synth 8-6014] Unused sequential element reg_count_reg was removed.
Should I take this warning message seriously? I looks like its valid code sythesizable VHDL code to me.

This is a problem with vivado 2017.1.
the xilinx forum talked about it: https://forums.xilinx.com/t5/Synthesis/Many-spurious-quot-Synth-8-6014-Unused-sequential-element-was/td-p/769636
You can safely ignore this warning as it doesn't affect you synthesis result.

Related

Object is used but not declared in VHDL

I'm doing a BCD counter that can count up/down depending on the input signals. This is the requirement:
This is my VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- main
entity BCDcounter is
port(
D_in: in std_logic_vector(3 downto 0);
enable_in, load_in, up_in, clr_in, clk_50hz: in std_logic;
C_out: out std_logic;
LED0: out std_logic_vector(0 to 6)
);
end BCDcounter;
architecture Behavioral of BCDcounter is
signal Q_temp: std_logic_vector(3 downto 0);
signal clk_1hz: std_logic;
component Clock_Divider is
port ( clk,reset: in std_logic;
clock_out: out std_logic);
end component;
component BCD_counter is
port(
D: in std_logic_vector(3 downto 0);
enable, load, up, clr, clk: in std_logic;
Q: std_logic_vector(3 downto 0);
Cout: out std_logic
);
end component;
component led IS
PORT ( input : IN STD_LOGIC_VECTOR(3 downto 0);
output : OUT STD_LOGIC_VECTOR(6 downto 0));
end component;
begin
stage0: Clock_Divider port map(clk_50hz, clr_in, clk_1hz);
stage1: BCD_counter port map(D_in, enable_in, load_in, up_in, clr_in, clk_1hz, Q_temp, C_out);
stage2: led port map(Q_temp, LED0);
end Behavioral;
-- 1-digit BCD counter
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BCD_counter is
port(
D: in std_logic_vector(3 downto 0);
enable, load, up, clr, clk: in std_logic;
Q: std_logic_vector(3 downto 0);
Cout: out std_logic
);
end BCD_counter;
architecture bhv of BCDcounter is
signal temp: std_logic_vector(3 downto 0);
begin
process(enable, load, up, clr, clk)
begin
if clr = '0' then
temp <= "0000";
elsif enable = '0' then
temp <= "0000";
elsif load = '1' then -- load = 1, enable = 1
temp <= D;
elsif(rising_edge(clk)) then -- load = 0, enable = 1
if up = '1' then -- count up
if temp = "1001" then
temp <= "0000";
Cout <= '1';
else
temp <= temp + 1;
end if;
else -- count down
if temp = "0000" then
temp <= "1001";
Cout <= '1';
else
temp <= temp - 1;
end if;
end if;
end if;
end process;
Q <= temp;
end bhv;
-- Clock Divider from 50MHz to 1Hz
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity Clock_Divider is
port ( clk,reset: in std_logic;
clock_out: out std_logic);
end Clock_Divider;
architecture behavioral of Clock_Divider is
signal count: integer:=1;
signal tmp : std_logic := '0';
begin
process(clk,reset)
begin
if(reset='1') then
count <= 1;
tmp <= '0';
elsif(clk'event and clk='1') then
count <= count+1;
if (count = 25000000) then
tmp <= NOT tmp;
count <= 1;
end if;
end if;
clock_out <= tmp;
end process;
end behavioral;
-- LED 7 segments
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY led IS
PORT ( input : IN STD_LOGIC_VECTOR(3 downto 0);
output : OUT STD_LOGIC_VECTOR(6 downto 0));
END led;
ARCHITECTURE behave OF led IS
BEGIN
PROCESS(input)
BEGIN
CASE input IS -- abcdefg
WHEN "0000" => output <= "0000001";
WHEN "0001" => output <= "1001111";
WHEN "0010" => output <= "0010010";
WHEN "0011" => output <= "0000110";
WHEN "0100" => output <= "1001100";
WHEN "0101" => output <= "0100100";
WHEN "0110" => output <= "0100000";
WHEN "0111" => output <= "0001111";
WHEN "1000" => output <= "0000000";
WHEN "1001" => output <= "0000100";
WHEN OTHERS => output <= "1111111";-- ALL OFF
END CASE;
END PROCESS;
END behave;
When compiling, I meet the error like this although I have already declared them above. Can anyone show me what problem with my code and how to fix this error? Thank you so much.
Your entity is called BCD_counter
entity BCD_counter is
but you have created the architecture for BCDCounter
architecture bhv of BCDcounter is
And it is quite correct, BCD_Counter has no object called clr or any of the other objects it lists.
Be careful when naming entities. I also recommend putting one entity/architecture pair per file, with the prefered method to name the file the same as the entity.

VHDL Microprocessor 16 bits

I'm trying to make a microprocessor architecture and I'm stuck. My accumulator, IR and PC don't seem to be working and I can't figure out why.
their outputs stay always undefined. I check the mapping and the other components of the mp they're are all correct the problem is somewhere in these registers.
------------------------------------------------------
-- ALU
------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.up_pack.all;
entity alu is
port ( A, B : in std_logic_vector(15 downto 0);
alufs : in ALU_FCTS;
S : out std_logic_vector( 15 downto 0));
end alu;
architecture arch_alu of alu is
begin
S <= "0000000000000000"; -- sortie par défaut
process(A, B, alufs)
begin
case alufs is
when ALU_B => S <= B;
when ALU_SUB => S <= std_logic_vector(unsigned(B) - unsigned(A));
when ALU_ADD => S <= std_logic_vector(unsigned(B) + unsigned(A));
when ALU_B_INC => S <= std_logic_vector(unsigned(B) + 1);
when ALU_AND => S <= A and B;
when ALU_OR => S <= A or B;
when ALU_XOR => S <= A xor B;
when others => S <= "0000000000000000";
end case;
end process;
end arch_alu;
------------------------------------------------------
-- ACCUMULATER
------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity accumulator is
port( clk, raz, load : in std_logic;
data_in : in std_logic_vector(15 downto 0);
data_out : out std_logic_vector(15 downto 0);
acc15, accz : out std_logic );
end accumulator;
architecture arch_acc of accumulator is
signal q_reg : std_logic_vector(15 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if raz='1' then q_reg <= (others => '0');
elsif load='1' then q_reg <= std_logic_vector(unsigned(q_reg) + unsigned(data_in)); end if;
end if;
end process;
data_out <= q_reg;
acc15 <= q_reg(15);
accz <= '1' when q_reg = "0000000000000000";
end arch_acc;
------------------------------------------------------
-- REGISTER PC
------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity pc_reg is
port( clk, raz, load : in std_logic;
data_in : in std_logic_vector(11 downto 0);
data_out : out std_logic_vector(11 downto 0) );
end pc_reg;
architecture arch_pc_reg of pc_reg is
signal interne : std_logic_vector(11 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if raz='1' then interne <= (others => '0');
elsif load='1' then interne <= data_in;
end if;
end if;
end process;
data_out <= interne;
end arch_pc_reg;
------------------------------------------------------
-- IR (Instruction Register)
------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.up_pack.all;
entity ir_reg is
port( clk, raz, load : in std_logic;
data_in : in std_logic_vector(15 downto 0);
data_out : out std_logic_vector(11 downto 0);
opcode : out OPCODE);
end ir_reg;
architecture arch_ir_reg of ir_reg is
signal interne : std_logic_vector(3 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if raz='1' then data_out <= (others => '0');
elsif load='1'
then
data_out <= data_in(11 downto 0);
interne <= data_in(15 downto 12);
end if;
end if;
end process;
opcode <= OP_LDA when interne="0000" else
OP_STO when interne="0001" else
OP_ADD when interne="0010" else
OP_SUB when interne="0011" else
OP_JMP when interne="0100" else
OP_JGE when interne="0101" else
OP_JNE when interne="0110" else
OP_STP when interne="0111" else
OP_AND when interne="1000" else
OP_OR when interne="1001" else
OP_XOR when interne="1010" else
OP_LDR when interne="1011" else
OP_LDI when interne="1100" else
OP_STI when interne="1101" else
OP_JSR when interne="1110" else
OP_RET when interne="1111" else
OP_UNKNOWN;
end arch_ir_reg;
This is not an answer, but a testbench for you to work with. Your accumulator seems to work fine. I tested it with the testbench below. Use it as resource for writing testbenches for the rest of your modules. (You can write a test bench to test all the modules together or individually, just FYI)
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity tb_accumulator is
end tb_accumulator;
architecture behav of tb_accumulator is
signal clk : std_logic := '0';
signal raz : std_logic := '1';
signal load : std_logic := '0';
signal data_in : std_logic_vector(15 downto 0) := (others => '0');
signal data_out : std_logic_vector(15 downto 0) := (others => '0');
signal acc15 : std_logic := '0';
signal accz : std_logic := '0';
begin
--Assign values for signals being passed into accumulator.
clk <= not clk after 2.5 ns;
data_in <= "0000000000000001";
raz <= '0' after 90 ns; --You can do this instead of forcing a signal. Set at what times you want it to change values.
load <= '1' after 100 ns;
accu_inst : entity work.accumulator
port map(
clk => clk,
raz => raz,
load => load,
data_in => data_in,
data_out => data_out,
acc15 => acc15,
accz=> accz
);
end behav;

How to add std_logic to an integer value

I am trying to run two 7 segments here, I have searched everywhere but could not find a satisfactory reply, how can I add 1 to a std_logic ? I tried the logic_arith library as well but nothing works. I read somewhere that i gotta use a (0 to 0) vector but umm i didn't really get that part. Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
entity blah is
Port ( clk : in STD_LOGIC;
anode: out STD_LOGIC_VECTOR (3 downto 0);
segment: out STD_LOGIC_VECTOR (6 downto 0));
end blah;
architecture Behavioral of blah is
signal sel: STD_LOGIC;
signal r_anode: STD_LOGIC_VECTOR (3 downto 0);
begin
anode <= r_anode;
process (clk) begin
if (clk'event and clk = '1') then
sel <= sel+1;
end if;
end process;
process (sel) begin
case sel is
when '0' => r_anode <= "1110";
when '1' => r_anode <= "1101";
when others => r_anode <= "1111";
end case;
case r_anode is
when "1110" => segment <= "0100100";
when "1101" => segment <= "0010010";
when others => segment <= "1111111";
end case;
end process;
end;
And the error
ERROR:HDLParsers:808 - "E:/Xilinx Projects/blah/blah.vhd" Line 19. + can not have such operands in this context.
The sel is only a single bit, so adding 1 is like a not sel.
However, if sel is more bits in a std_logic_vector, you can add a
natural to std_logic_vector as unsigned with:
sel <= std_logic_vector(unsigned(sel) + 1);
Use only ieee.numeric_std, thus remove the ieee.std_logic_arith, since
std_logic_arith is not a standard library (Synopsys proprietary).

Parse error, unexpected STRING_LITERAL, expecting PIPE or ROW VHDL

I am trying to implement 32x32 Register File in VHDL. I have been struggling with this issue for a while... More specifically, I get the following error when I try to compile the code:
HDLParsers:164 - "//vmware-host/shared folders/Shared from MAIN/decoder.vhd" Line 26. parse error, unexpected STRING_LITERAL, expecting PIPE or ROW
I have tried variety of different solutions and none of them worked.
I am placing all the entities as they appear in the top level system.
The top level system:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library work;
use work.array_pkg.all;
entity GenRegisters is
port( Rd_Data : in std_logic_vector(31 downto 0);
Rs, Rt, Rd : in std_logic_vector(4 downto 0);
Reg_Write : in std_logic; -- enable
Rs_Output: out std_logic_vector(31 downto 0);
Rt_Output: out std_logic_vector(31 downto 0);
CLK, RESET : in std_logic -- clock and reset
);
end GenRegisters;
architecture Behavioural of GenRegisters is
signal decoder_out : std_logic_vector(31 downto 0);
signal DOUT: std_logic_vector(31 downto 0);
-- component declaration
component Register32
port (
DIN : in std_logic_vector(31 downto 0); -- system inputs
DOUT : out std_logic_vector(31 downto 0); -- system outputs
ENABLE : in std_logic_vector (0 downto 0); -- enable
CLK, RESET : in std_logic -- clock and reset
);
end component; -- end component;
-- component declaration
component Mux32t5
port (
Registers : in array2d; -- system inputs
Rselect : in std_logic_vector(4 downto 0);
Rout : out std_logic_vector(31 downto 0) -- system outputs
);
end component; -- end component;
-- component declaration
component decoder
port (
enable : in std_logic; -- enable
binary_in: in std_logic_vector(4 downto 0); -- system inputs
decoder_out: out std_logic_vector(31 downto 0) -- system outputs
);
end component; -- end component;
begin
-- VHDL Generalte allows you to replicate components, see hep
Decoder_1: decoder
port map(Reg_write, Rd, decoder_out);
GEN_ADD: for I in 0 to 31 generate
Register32D:Register32 port map
(Rd_Data, DOUT, decoder_out(I), CLK, RESET); -- :)
end generate GEN_ADD;
Mux_Rt: Mux32t5
port map(Register32D, Rt, Rt_Output);
Mux_Rs: Mux32t5
port map(Register32D, Rs, Rs_Output);
end Behavioural;
Decoder entity:
-------------------------------------------------------
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity decoder is
port(
enable :in std_logic; -- Enable for the decoder
binary_in :in std_logic_vector (4 downto 0); -- 5-bit Input
decoder_out :out std_logic_vector (31 downto 0) -- 32-bit Output
);
end decoder;
architecture Behavioural of decoder is
begin
process (enable, binary_in)
begin
decoder_out <= X"00000000";
if (enable = '1') then
case (binary_in) is
when 5x"00" => decoder_out <= X"00000001";
when 5x"01" => decoder_out <= X"00000002";
when 5x"02" => decoder_out <= X"00000004";
when 5x"03" => decoder_out <= X"00000008";
when 5x"04" => decoder_out <= X"00000010";
when 5x"05" => decoder_out <= X"00000020";
when 5x"06" => decoder_out <= X"00000040";
when 5x"07" => decoder_out <= X"00000080";
when 5x"08" => decoder_out <= X"00000100";
when 5x"09" => decoder_out <= X"00000200";
when 5x"0A" => decoder_out <= X"00000400";
when 5x"0B" => decoder_out <= X"00000800";
when 5x"0C" => decoder_out <= X"00001000";
when 5x"0D" => decoder_out <= X"00002000";
when 5x"0E" => decoder_out <= X"00004000";
when 5x"0F" => decoder_out <= X"00008000";
when 5x"10" => decoder_out <= X"00010000";
when 5x"11" => decoder_out <= X"00020000";
when 5x"12" => decoder_out <= X"00040000";
when 5x"13" => decoder_out <= X"00080000";
when 5x"14" => decoder_out <= X"00100000";
when 5x"15" => decoder_out <= X"00200000";
when 5x"16" => decoder_out <= X"00400000";
when 5x"17" => decoder_out <= X"00800000";
when 5x"18" => decoder_out <= X"01000000";
when 5x"19" => decoder_out <= X"02000000";
when 5x"1A" => decoder_out <= X"04000000";
when 5x"1B" => decoder_out <= X"08000000";
when 5x"1C" => decoder_out <= X"10000000";
when 5x"1D" => decoder_out <= X"20000000";
when 5x"1E" => decoder_out <= X"40000000";
when 5x"1F" => decoder_out <= X"80000000";
when others => decoder_out <= X"00000000";
end case;
end if;
end process;
end Behavioural;
Register32:
-------------------------------------------------------
-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Register32 is
port (
DIN : in std_logic_vector(31 downto 0); -- system inputs
DOUT : out std_logic_vector(31 downto 0); -- system outputs
ENABLE : in std_logic_vector(0 downto 0);
CLK, RESET : in std_logic -- clock and reset
);
end Register32;
architecture Behavioural of Register32 is
begin
process(CLK,RESET)
begin -- process
-- activities triggered by asynchronous reset (active high)
if RESET = '1' then DOUT <= "00000000000000000000000000000000";
-- activities triggered by rising edge of clock
elsif CLK'event and CLK = '1' then
if ENABLE='1' then DOUT <= DIN;
else null;
end if;
end if;
end process;
end Behavioural;
MUX_Rt:
-------------------------------------------------------
-------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.array_pkg.all;
-- define inputs and outputs
entity Mux32t5 is
port(
Registers : in array2d;
RSelect : in std_logic_vector(4 downto 0);
Rout : out std_logic_vector(31 downto 0) );
end Mux32t5;
architecture Behavioural of Mux32t5 is
begin
with Rselect select
Rout <= Registers(0) when 5X"00",
Registers(1) when 5X"01",
Registers(2) when 5X"02",
Registers(3) when 5X"03",
Registers(4) when 5X"04",
Registers(5) when 5X"05",
Registers(6) when 5X"06",
Registers(7) when 5X"07",
Registers(8) when 5X"08",
Registers(9) when 5X"09",
Registers(10) when 5X"0A",
Registers(11) when 5X"0B",
Registers(12) when 5X"0C",
Registers(13) when 5X"0D",
Registers(14) when 5X"0E",
Registers(15) when 5X"0F",
Registers(16) when 5X"10",
Registers(17) when 5X"11",
Registers(18) when 5X"12",
Registers(19) when 5X"13",
Registers(20) when 5X"14",
Registers(21) when 5X"15",
Registers(22) when 5X"16",
Registers(23) when 5X"17",
Registers(24) when 5X"18",
Registers(25) when 5X"19",
Registers(26) when 5X"1A",
Registers(27) when 5X"1B",
Registers(28) when 5X"1C",
Registers(29) when 5X"1D",
Registers(30) when 5X"1E",
Registers(31) when 5X"1F",
X"0000" when others;
end Behavioural;
MUX_Rs:
-------------------------------------------------------
-------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.array_pkg.all;
-- define inputs and outputs
entity Mux32t5 is
port(
Registers : in array2d;
RSelect : in std_logic_vector(4 downto 0);
Rout : out std_logic_vector(31 downto 0) );
end Mux32t5;
architecture Behavioural of Mux32t5 is
begin
with Rselect select
Rout <= Registers(0) when 5X"00",
Registers(1) when 5X"01",
Registers(2) when 5X"02",
Registers(3) when 5X"03",
Registers(4) when 5X"04",
Registers(5) when 5X"05",
Registers(6) when 5X"06",
Registers(7) when 5X"07",
Registers(8) when 5X"08",
Registers(9) when 5X"09",
Registers(10) when 5X"0A",
Registers(11) when 5X"0B",
Registers(12) when 5X"0C",
Registers(13) when 5X"0D",
Registers(14) when 5X"0E",
Registers(15) when 5X"0F",
Registers(16) when 5X"10",
Registers(17) when 5X"11",
Registers(18) when 5X"12",
Registers(19) when 5X"13",
Registers(20) when 5X"14",
Registers(21) when 5X"15",
Registers(22) when 5X"16",
Registers(23) when 5X"17",
Registers(24) when 5X"18",
Registers(25) when 5X"19",
Registers(26) when 5X"1A",
Registers(27) when 5X"1B",
Registers(28) when 5X"1C",
Registers(29) when 5X"1D",
Registers(30) when 5X"1E",
Registers(31) when 5X"1F",
X"0000" when others;
end Behavioural;
array_pkg:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
package array_pkg is
TYPE array2d IS ARRAY(31 DOWNTO 0) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
END array_pkg;
Can anyone provide some clues or solution for the problem please?
For your multiplexor you might consider a simpler alternate solution and replace the case statement with
use ieee.numeric_std.all ;
architecture Behavioural of Mux32t5 is
begin
ROut <= registers (to_integer(unsigned(binary_in))) ;
end Behavioural ;
Or alternately with the unsigned package (note this one requires VHDL-2008):
use ieee.numeric_std_unsigned.all ;
...
ROut <= registers (to_integer(binary_in)) ;
It looks like you're trying to use VHDL-2008 conventions for that case statement and the compiler is not happy with you. Try this in your decoder.vhd:
case (binary_in) is
when "00000" => decoder_out <= X"00000001";
when "00001" => decoder_out <= X"00000002";
when "00010" => decoder_out <= X"00000004";
when "00011" => decoder_out <= X"00000008";
Etc...

Why Does This VHDL Work in Sumulation and Does not Work on the Virtex 5 Device

I have spent the whole day trying to solve the following problem. I am building a small averaging multichannel oscilloscope and I have the following module for storing the signal:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
entity storage is
port
(
clk_in : in std_logic;
reset : in std_logic;
element_in : in std_logic;
data_in : in std_logic_vector(11 downto 0);
addr : in std_logic_vector(9 downto 0);
add : in std_logic; -- add = '1' means add to RAM
-- add = '0' means write to RAM
dump : in std_logic;
element_out : out std_logic;
data_out : out std_logic_vector(31 downto 0)
);
end storage;
architecture rtl of storage is
component bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end component bram;
type state is (st_startwait, st_add, st_write);
signal current_state : state := st_startwait;
signal next_state : state := st_startwait;
signal start : std_logic;
signal we : std_logic;
signal en : std_logic;
signal di : std_logic_vector(31 downto 0);
signal do : std_logic_vector(31 downto 0);
signal data : std_logic_vector(11 downto 0);
begin
ram : bram port map
(
clk => clk_in,
we => we,
en => en,
addr => addr,
di => di,
do => do
);
process(clk_in, reset, start)
begin
if rising_edge(clk_in) then
if (reset = '1') then
current_state <= st_startwait;
else
start <= '0';
current_state <= next_state;
if (element_in = '1') then
start <= '1';
end if;
end if;
end if;
end process;
process(current_state, start, dump)
variable acc : std_logic_vector(31 downto 0);
begin
element_out <= '0';
en <= '1';
we <= '0';
case current_state is
when st_startwait =>
if (start = '1') then
acc(11 downto 0) := data_in;
acc(31 downto 12) := (others => '0');
next_state <= st_add;
else
next_state <= st_startwait;
end if;
when st_add =>
if (add = '1') then
acc := acc + do;
end if;
we <= '1';
di <= acc;
next_state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc;
element_out <= '1';
end if;
next_state <= st_startwait;
end case;
end process;
end rtl;
Below is the BRAM module as copied from the XST manual. This is a no-change type of BRAM and I believe there is the problem. The symptom is that, while this simulates fine, I read only zeroes from the memory when I use the design on the device.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(9 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end bram;
architecture rtl of bram is
type ram_type is array (0 to 999) of std_logic_vector (31 downto 0);
signal buf : ram_type;
begin
process(clk, en, we)
begin
if rising_edge(clk) then
if en = '1' then
if we = '1' then
buf(conv_integer(addr)) <= di;
else
do <= buf(conv_integer(addr));
end if;
end if;
end if;
end process;
end rtl;
What follows is a description of the chip use and the expected output. "clk_in" is a 50 MHz clock. "element_in" is '1' for 20 ns and '0' for 60 ns. "addr_in" iterates from 0 to 999 and changes every 80 ns. "element_in", "data_in", and "addr" are all aligned and synchronous. Now "add" is '1' for 1000 elements, then both "add" and "dump" are zero for 8000 elements and, finally "dump" is '1' for 1000 elements. Now, if I have a test bench that supplies "data_in" from 0 to 999, I expect data_out to be 0, 10, 20, 30, ..., 9990 when "dump" is '1'. That is according to the simulation. In reality I get 0, 1, 2, 3, ..., 999....
Some initial issues to address are listed below.
The process(current_state, start, dump) in storage entity looks like it is
intended to implement a combinatorial element (gates), but the signal (port)
data_in is not in the sensitivity list.
This is very likely to cause a difference between simulation and synthesis
behavior, since simulation will typically only react to the signals in the
sensitivity list, where synthesis will implement the combinatorial design and
react on all used signals, but may give a warning about incomplete sensitivity
list or inferred latches. If you are using VHDL-2008 then use can use a
sensitivity list of (all) to have the process sensitivity to all used
signals, and otherwise you need to add missing signals manually.
The case current_state is in process(current_state, start, dump) lacks an
when others => ..., so the synthesis tool has probably given you a warning
about inferred latches. This should be fixed by adding the when others =>
with and assign all signals driven by the process to the relevant value.
The use clause lists:
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
But both of these should not be used at the same time, since they declare some
of the same identifiers, for example is unsigned declared in both. Since the
RAM uses std_logic_unsigned I suggest that you stick with that only, and
delete use of numeric_std. For new code I would though recommend use of
numeric_std.
Also the process(clk_in, reset, start) in storage entity implements a
sequential element (flip flop) sensitive to only rising edge of clk_in, so
the two last signals in sensitivity list ..., reset, start) are unnecessary,
but does not cause a problem.

Resources