Warnings XST1293 and XST1896 during synthesis - vhdl

I am currently working on a game using VHDL as a programming language. I have been able to avoid laches from the start but on this one, I am completely lost...
I try to increment the level number when my small Mario reaches the end platform (to switch to the next level). So when he reaches this platform the signal nextLevel_i worth '1'.
I have implemented the code as follow:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;
entity level is
port (
clk_i : in std_Logic;
reset_i : in std_Logic;
nextLevel_i : in std_Logic;
elem01_o : out std_logic_vector (13 downto 0);
elem02_o : out std_logic_vector (13 downto 0);
elem03_o : out std_logic_vector (13 downto 0);
elem04_o : out std_logic_vector (13 downto 0);
elem05_o : out std_logic_vector (13 downto 0);
elem06_o : out std_logic_vector (13 downto 0);
elem07_o : out std_logic_vector (13 downto 0);
elem08_o : out std_logic_vector (13 downto 0);
elem09_o : out std_logic_vector (13 downto 0);
elem10_o : out std_logic_vector (13 downto 0);
elem11_o : out std_logic_vector (13 downto 0);
elem12_o : out std_logic_vector (13 downto 0);
elem13_o : out std_logic_vector (13 downto 0);
elem14_o : out std_logic_vector (13 downto 0);
elem15_o : out std_logic_vector (13 downto 0);
elem16_o : out std_logic_vector (13 downto 0);
elem17_o : out std_logic_vector (13 downto 0);
elem18_o : out std_logic_vector (13 downto 0);
elem19_o : out std_logic_vector (13 downto 0);
elem20_o : out std_logic_vector (13 downto 0)
);
end level;
architecture Behavioral of level is
signal currentLevel_s : integer range 0 to 127 := 0;
begin
processLevel : process (currentLevel_s)
begin
elem01_o <= (others => '0');
elem02_o <= (others => '0');
elem03_o <= (others => '0');
elem04_o <= (others => '0');
elem05_o <= (others => '0');
elem06_o <= (others => '0');
elem07_o <= (others => '0');
elem08_o <= (others => '0');
elem09_o <= (others => '0');
elem10_o <= (others => '0');
elem11_o <= (others => '0');
elem12_o <= (others => '0');
elem13_o <= (others => '0');
elem14_o <= (others => '0');
elem15_o <= (others => '0');
elem16_o <= (others => '0');
elem17_o <= (others => '0');
elem18_o <= (others => '0');
elem19_o <= (others => '0');
elem20_o <= (others => '0');
case currentLevel_s is
when 1 =>
elem01_o <= "11111001010000";
elem02_o <= "01110000110000";
elem03_o <= "01110001010000";
elem04_o <= "01110001110000";
elem05_o <= "01110010010000";
elem06_o <= "01110010110000";
elem07_o <= "01110011010000";
elem08_o <= "01110011110000";
elem09_o <= "01110100010000";
elem10_o <= "01110100110000";
elem11_o <= "01110101010000";
elem12_o <= "01110101110000";
elem13_o <= "01110110010000";
elem14_o <= "01110110110000";
elem15_o <= "01110111010000";
elem16_o <= "01110111110000";
elem17_o <= "01111000010000";
elem18_o <= "01111000110000";
elem19_o <= "01110011101101";
elem20_o <= "01110100001100";
when 2 =>
elem01_o <= "00010000010010";
when others =>
elem01_o <= "00100001010000";
elem02_o <= "11111001010000";
end case;
end process processLevel;
----------------------
-- nextLevel Logic
----------------------
processNextLevel : process (clk_i, reset_i)
begin
if (reset_i = '1') then
currentLevel_s <= 0;
elsif rising_edge(clk_i) then
if (nextLevel_i = '1') then
currentLevel_s <= currentLevel_s + 1;
end if;
end if;
end process processNextLevel;
end Behavioral;
Note: currentLevel_s is declared as follow:
signal currentLevel_s : integer range 0 to 127 := 0;
I have then launched the synthesis and I get the following results:
I think this result occurs because I do not affect a value to currentLevel_s (no else clause after the if (reset_i = '1') then). I simply want to keep the current value if the condition is not filled.
Any ideas how to solve these warnings ?

This is an easy one:
You only do something when currentLevel_s is 1 ("01") or 2 ("10"). All other values don't matter. The synthesis tool optimizes away all other values.
Try adding when 127 => [something].
Or just
signal currentLevel_s : integer range 0 to 3 := 0;
if nextLevel_i = '1' and currentLevel_s < 3 then
currentLevel_s <= currentLevel_s + 1;
end if;

Related

VHDL: Cache memory output signal not consistent and varies between either halfs of the output being right, but never the whole thing

I hope you guys are well :)
I am trying to implement a simple cache memory system, however I am finding myself unable to properly do so. When I attempt to test my read miss/ read hit, I am getting the following result: VHDL Signals.
As I understand my design, the Read Miss state should be writing 1011111110101100 however I am either getting 10111111100000000 or 00000010101100. My result seems to fluctuate between both results. s_addr refers to a new instruction from the CPU which starts one process, which in turn starts the state process should there be any changes. I have provided some code. I am unsure of how to proceed. I've walked through my code and I do not understand why it splits the values like that when the output was supposed occur in one go.
Finally, I suspect that this may have something to do with the fact that my signals are initially undefined for some reason.
Full signal diagram
I am not sure why for the first 6ns, the output of s_readdatta is undefined. My tag values stored in test1 and test2 are also undefined and I am not sure why. I would appreciate any insight you guys can offer. Thank you!
VHDL code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_bit_unsigned.all;
entity cache is
generic(
ram_size : INTEGER := 32768
);
port(
clock : in std_logic;
reset : in std_logic;
-- Avalon interface --
s_addr : in std_logic_vector (31 downto 0);
s_read : in std_logic;
s_readdata : out std_logic_vector (31 downto 0);
s_write : in std_logic;
s_writedata : in std_logic_vector (31 downto 0);
s_waitrequest : out std_logic;
m_addr : out integer range 0 to ram_size-1;
m_read : out std_logic;
m_readdata : in std_logic_vector (7 downto 0);
m_write : out std_logic;
m_writedata : out std_logic_vector (7 downto 0);
m_waitrequest : in std_logic;
test1: out std_logic_vector (5 downto 0);
test2: out std_logic_vector (5 downto 0)
);
end cache;
architecture arch of cache is
-- declare signals here
-- 15 bit signal will be of the following form: VDTTTTBBBBBWWbb
constant number_of_cache_lines: integer := 128;
TYPE t_cache_memory IS ARRAY(number_of_cache_lines-1 downto 0) OF STD_LOGIC_VECTOR(31 downto 0);
-- For data requested by CPU
signal tag_bits: std_logic_vector (5 downto 0);
signal block_index: std_logic_vector (4 downto 0);
signal block_index_int: integer;
signal word_index: std_logic_vector (1 downto 0);
signal word_index_int: integer;
-- For data in the cache
signal in_cache_tag_bits: std_logic_vector (5 downto 0);
signal in_cache_valid_bit: std_logic;
signal in_cache_dirty_bit: std_logic;
signal temp_s_addr: std_logic_vector(14 downto 0);
signal retrieved_address: std_logic_vector (31 downto 0);
type t_State is (readHit, writeHit, writeBack, readMiss, writeMiss, idle);
signal state: t_State;
signal cache_memory: t_cache_memory;
begin
-- For CPU address
temp_s_addr(3 downto 0) <= (others => '0');
temp_s_addr(14 downto 4) <= s_addr (14 downto 4);
tag_bits <= s_addr (14 downto 9);
block_index <= s_addr (8 downto 4);
block_index_int <= 4*to_integer(unsigned(block_index));
word_index <= s_addr (3 downto 2);
word_index_int <= to_integer(unsigned(word_index));
process (s_addr)
begin
if block_index_int /= -2147483648 then
retrieved_address <= cache_memory(block_index_int + word_index_int);
in_cache_valid_bit <= cache_memory(block_index_int)(15);
in_cache_dirty_bit <= cache_memory(block_index_int)(14);
in_cache_tag_bits <= cache_memory(block_index_int)(13 downto 8);
end if;
if s_read = '1' and s_write ='0' then
if in_cache_valid_bit = '1' then
test1 <= s_addr (14 downto 9);
test2 <= in_cache_tag_bits;
if in_cache_tag_bits = s_addr (14 downto 9) then
state <= readHit;
else
if in_cache_dirty_bit = '1' then
state <= writeBack;
else
state <= readMiss;
end if;
end if;
else
state <= readMiss;
end if;
elsif s_write = '1' and s_read = '0' then
if in_cache_valid_bit = '1' then
if tag_bits = in_cache_tag_bits then
state <= writeHit;
else
if in_cache_dirty_bit = '1' then
state <= writeBack;
else
state <= writeMiss;
end if;
end if;
end if;
else
state <= idle;
end if;
end process;
process(state)
begin
s_waitrequest <= '1';
case state is
-- If CPU is not doing anything
when idle =>
report "No Reads or Writes have occured.";
when readHit =>
report "Read Hit Occured:";
s_readdata <= retrieved_address;
-- If write hit
when writeHit =>
report "Write Hit Occured:";
cache_memory(block_index_int + word_index_int)(7 downto 0) <= s_addr(7 downto 0);
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '1';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
-- If cache hit but dirty bit then write-back
when writeBack =>
report "Write Back Occured:";
-- Write back into memory first
m_write <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
m_writedata <= temp_s_addr(7 downto 0);
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 4;
m_writedata(3 downto 0) <= "0100";
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 8;
m_writedata(3 downto 0) <= "1000";
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 12;
m_writedata(3 downto 0) <= "1100";
m_write <= '0';
-- Write to cache
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '0';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
when readMiss =>
report "Read Miss Occured:";
m_read <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
cache_memory(block_index_int)(7 downto 0) <= m_readdata;
cache_memory(block_index_int)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+4;
cache_memory(block_index_int+1)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+1)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+8;
cache_memory(block_index_int+2)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+2)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+12;
cache_memory(block_index_int+3)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+3)(31 downto 8) <= (others => '0');
m_read <= '0';
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
s_readdata<= cache_memory(block_index_int + word_index_int);
--state <= idle;
-- If write miss
when writeMiss =>
report "Write Miss Occured:";
m_write <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + word_index_int;
m_writedata <= s_addr(7 downto 0);
m_write <= '0';
m_read <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
cache_memory(block_index_int)(7 downto 0) <= m_readdata;
cache_memory(block_index_int)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+4;
cache_memory(block_index_int+1)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+1)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+8;
cache_memory(block_index_int+2)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+2)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+12;
cache_memory(block_index_int+3)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+3)(31 downto 8) <= (others => '0');
m_read <= '0';
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
end case;
s_waitrequest <= '0';
end process;
end arch;
Testbench Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cache_tb is
end cache_tb;
architecture behavior of cache_tb is
component cache is
generic(
ram_size : INTEGER := 32768
);
port(
clock : in std_logic;
reset : in std_logic;
-- Avalon interface --
s_addr : in std_logic_vector (31 downto 0);
s_read : in std_logic;
s_readdata : out std_logic_vector (31 downto 0);
s_write : in std_logic;
s_writedata : in std_logic_vector (31 downto 0);
s_waitrequest : out std_logic;
m_addr : out integer range 0 to ram_size-1;
m_read : out std_logic;
m_readdata : in std_logic_vector (7 downto 0);
m_write : out std_logic;
m_writedata : out std_logic_vector (7 downto 0);
m_waitrequest : in std_logic;
test1: out std_logic_vector (5 downto 0);
test2: out std_logic_vector (5 downto 0)
);
end component;
component memory is
GENERIC(
ram_size : INTEGER := 32768;
mem_delay : time := 10 ns;
clock_period : time := 1 ns
);
PORT (
clock: IN STD_LOGIC;
writedata: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address: IN INTEGER RANGE 0 TO ram_size-1;
memwrite: IN STD_LOGIC;
memread: IN STD_LOGIC;
readdata: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
waitrequest: OUT STD_LOGIC
);
end component;
-- test signals
signal reset : std_logic := '0';
signal clk : std_logic := '0';
constant clk_period : time := 1 ns;
signal s_addr : std_logic_vector (31 downto 0);
signal s_read : std_logic;
signal s_readdata : std_logic_vector (31 downto 0);
signal s_write : std_logic;
signal s_writedata : std_logic_vector (31 downto 0);
signal s_waitrequest : std_logic;
signal m_addr : integer range 0 to 2147483647;
signal m_read : std_logic;
signal m_readdata : std_logic_vector (7 downto 0);
signal m_write : std_logic;
signal m_writedata : std_logic_vector (7 downto 0);
signal m_waitrequest : std_logic;
signal test1: std_logic_vector (5 downto 0);
signal test2: std_logic_vector (5 downto 0);
begin
-- Connect the components which we instantiated above to their
-- respective signals.
dut: cache
port map(
clock => clk,
reset => reset,
s_addr => s_addr,
s_read => s_read,
s_readdata => s_readdata,
s_write => s_write,
s_writedata => s_writedata,
s_waitrequest => s_waitrequest,
m_addr => m_addr,
m_read => m_read,
m_readdata => m_readdata,
m_write => m_write,
m_writedata => m_writedata,
m_waitrequest => m_waitrequest,
test1 => test1,
test2 => test2
);
MEM : memory
port map (
clock => clk,
writedata => m_writedata,
address => m_addr,
memwrite => m_write,
memread => m_read,
readdata => m_readdata,
waitrequest => m_waitrequest
);
clk_process : process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
test_process : process
begin
REPORT "***Initializing***";
s_read <= '0';
s_write <= '0';
s_addr <= "00000000000000000000000000000000";
wait for clk_period;
report "Initializing Zero complete...";
report "***Start Testing***";
report "Read Miss Test:";
s_read <= '1';
s_write <= '0';
s_addr <= "11111111111111111111111110101111";
wait for clk_period;
assert s_readdata(7 downto 0) = m_readdata report "DATA NOT IN CACHE";
wait for clk_period;
report "Read Hit Test:";
s_read <= '1';
s_write <= '0';
s_addr <= "11111111111111111111111110101111";
wait for clk_period;
assert s_readdata(7 downto 0) = m_readdata report "DATA NOT IN CACHE";
wait for clk_period;
end process;
end;

How to sum STD_LOGIC_VECTOR in VHDL?

I'm trying to sum the sample values of 8 ADC's. Divide them by 8 and return the result via a DAC. I've made a case statement that provides the user to choose between summing the whole or just outputting one channel.
The problem that I encounter is that the result is "flickering". It often does what it must do, but sometimes it gives what it seems higher values.
Also the individual channels seem much much worse than the summed value. I got the feeling it synthesizes two different things for summing and individual channels or something.
I think it might have something do with how I sum the vectors, but I'm not experienced enough to tell if what I'm doing is wrong or not.
Does anybody perhaps know what I'm doing wrong.
The code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY sum IS
PORT(
CLK_IN : IN STD_LOGIC; -- 200MHz
RESET : IN STD_LOGIC;
SUM_EN : IN STD_LOGIC;
SUM_VALID : IN STD_LOGIC;
CHANNEL_IN_1 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_2 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_3 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_4 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_5 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_6 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_7 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
CHANNEL_IN_8 : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
MODE_DATA : IN std_logic_vector(3 DOWNTO 0);
DATA_OUT : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := x"80";
SUM_READY : OUT STD_LOGIC := '0');
END sum;
ARCHITECTURE behaviour OF sum IS
-- input output registers
SIGNAL r_sum_en : STD_LOGIC := '0';
SIGNAL r_sum_en_edge : STD_LOGIC := '0';
SIGNAL r_sum_valid : STD_LOGIC := '0';
SIGNAL r_sum_ready : STD_LOGIC := '0';
SIGNAL r_channel_in_1 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_2 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_3 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_4 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_5 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_6 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_7 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_channel_in_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := (others => '0');
SIGNAL r_mode_data : STD_LOGIC_VECTOR( 3 DOWNTO 0 ) := (others => '0');
SIGNAL r_data_out : STD_LOGIC_VECTOR( 7 DOWNTO 0 ) := x"80";
-- logic signals
TYPE machine IS (idle, initialise, summing, waiting, averaging, delivering);
SIGNAL state : machine;
BEGIN
r_channel_in_1 <= CHANNEL_IN_1 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_2 <= CHANNEL_IN_2 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_3 <= CHANNEL_IN_3 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_4 <= CHANNEL_IN_4 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_5 <= CHANNEL_IN_5 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_6 <= CHANNEL_IN_6 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_7 <= CHANNEL_IN_7 WHEN r_sum_en = '1' ELSE x"80";
r_channel_in_8 <= CHANNEL_IN_8 WHEN r_sum_en = '1' ELSE x"80";
r_sum_en <= SUM_EN;
r_mode_data <= MODE_DATA;
r_sum_valid <= SUM_VALID;
DATA_OUT <= r_data_out;
SUM_READY <= r_sum_ready;
PROCESS (CLK_IN, RESET) IS
VARIABLE average : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_1 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_2 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_3 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_4 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_5 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_6 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_7 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
VARIABLE hold_channel_8 : STD_LOGIC_VECTOR(11 DOWNTO 0) := (others => '0');
BEGIN
IF RESET = '1' THEN
r_sum_ready <= '0';
r_data_out <= x"80";
hold_channel_1 := (others => '0');
hold_channel_2 := (others => '0');
hold_channel_3 := (others => '0');
hold_channel_4 := (others => '0');
hold_channel_5 := (others => '0');
hold_channel_6 := (others => '0');
hold_channel_7 := (others => '0');
hold_channel_8 := (others => '0');
ELSIF rising_edge(CLK_IN) THEN
CASE state IS
WHEN idle =>
r_sum_en_edge <= r_sum_en;
IF r_sum_en = '1' AND r_sum_en_edge = '0' THEN
state <= initialise;
ELSE state <= idle; END IF;
r_sum_ready <= '0';
r_sum_ready <= '0';
r_data_out <= x"80";
hold_channel_1 := x"080";
hold_channel_2 := x"080";
hold_channel_3 := x"080";
hold_channel_4 := x"080";
hold_channel_5 := x"080";
hold_channel_6 := x"080";
hold_channel_7 := x"080";
hold_channel_8 := x"080";
WHEN initialise =>
IF r_sum_valid = '1' THEN
state <= summing;
hold_channel_1(7 DOWNTO 0) := r_channel_in_1;
hold_channel_2(7 DOWNTO 0) := r_channel_in_2;
hold_channel_3(7 DOWNTO 0) := r_channel_in_3;
hold_channel_4(7 DOWNTO 0) := r_channel_in_4;
hold_channel_5(7 DOWNTO 0) := r_channel_in_5;
hold_channel_6(7 DOWNTO 0) := r_channel_in_6;
hold_channel_7(7 DOWNTO 0) := r_channel_in_7;
hold_channel_8(7 DOWNTO 0) := r_channel_in_8;
ELSE
state <= initialise;
END IF;
r_sum_ready <= '0';
WHEN summing =>
CASE r_mode_data IS
WHEN x"0" => average := hold_channel_1 + hold_channel_2 + hold_channel_3 + hold_channel_4 + hold_channel_5 + hold_channel_6 + hold_channel_7 + hold_channel_8 ;
WHEN x"1" => average := hold_channel_1;
WHEN x"2" => average := hold_channel_2;
WHEN x"3" => average := hold_channel_3;
WHEN x"4" => average := hold_channel_4;
WHEN x"5" => average := hold_channel_5;
WHEN x"6" => average := hold_channel_6;
WHEN x"7" => average := hold_channel_7;
WHEN x"8" => average := hold_channel_8;
WHEN others => null;
END CASE;
state <= waiting;
r_sum_ready <= '0';
WHEN waiting =>
state <= averaging;
r_sum_ready <= '0';
WHEN averaging =>
CASE r_mode_data IS
WHEN x"0" => r_data_out <= average (10 DOWNTO 3);
WHEN others => r_data_out <= average (7 DOWNTO 0);
END CASE;
r_sum_ready <= '0';
state <= delivering;
WHEN delivering =>
r_sum_ready <= '1';
IF r_sum_en = '1' THEN
state <= initialise;
ELSE state <= idle; END IF;
WHEN others =>
state <= idle;
END CASE;
END IF;
END PROCESS;
END ARCHITECTURE;

i have a vhdl code that take a 16 bit binary converts it to 5 bcd(4bit) how can i connect each bcd with a display?

i have a code that take a 16 bit binary converts it to 5 bcd(4bit)
how can i connect each bcd with a display?
the bcd 0 has to connect to the display 0 (seven segment display) so that the binary number is going to convert to decimal and display it on 5 seven segment displays
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity binary_bcd is
generic(N: positive := 16);
port(
clk, reset: in std_logic;
binary_in: in std_logic_vector(N-1 downto 0);
bcd0, bcd1, bcd2, bcd3, bcd4: out std_logic_vector(3 downto 0)
);
end binary_bcd ;
architecture behaviour of binary_bcd is
type states is (start, shift, done);
signal state, state_next: states;
signal binary, binary_next: std_logic_vector(N-1 downto 0);
signal bcds, bcds_reg, bcds_next: std_logic_vector(19 downto 0);
-- output register keep output constant during conversion
signal bcds_out_reg, bcds_out_reg_next: std_logic_vector(19 downto 0);
-- need to keep track of shifts
signal shift_counter, shift_counter_next: natural range 0 to N;
begin
process(clk, reset)
begin
if reset = '1' then
binary <= (others => '0');
bcds <= (others => '0');
state <= start;
bcds_out_reg <= (others => '0');
shift_counter <= 0;
elsif falling_edge(clk) then
binary <= binary_next;
bcds <= bcds_next;
state <= state_next;
bcds_out_reg <= bcds_out_reg_next;
shift_counter <= shift_counter_next;
end if;
end process;
convert:
process(state, binary, binary_in, bcds, bcds_reg, shift_counter)
begin
state_next <= state;
bcds_next <= bcds;
binary_next <= binary;
shift_counter_next <= shift_counter;
case state is
when start =>
state_next <= shift;
binary_next <= binary_in;
bcds_next <= (others => '0');
shift_counter_next <= 0;
when shift =>
if shift_counter = N then
state_next <= done;
else
binary_next <= binary(N-2 downto 0) & 'L';
bcds_next <= bcds_reg(18 downto 0) & binary(N-1);
shift_counter_next <= shift_counter + 1;
end if;
when done =>
state_next <= start;
end case;
end process;
bcds_reg(19 downto 16) <= bcds(19 downto 16) + 3 when bcds(19 downto 16) > 4 else
bcds(19 downto 16);
bcds_reg(15 downto 12) <= bcds(15 downto 12) + 3 when bcds(15 downto 12) > 4 else
bcds(15 downto 12);
bcds_reg(11 downto 8) <= bcds(11 downto 8) + 3 when bcds(11 downto 8) > 4 else
bcds(11 downto 8);
bcds_reg(7 downto 4) <= bcds(7 downto 4) + 3 when bcds(7 downto 4) > 4 else
bcds(7 downto 4);
bcds_reg(3 downto 0) <= bcds(3 downto 0) + 3 when bcds(3 downto 0) > 4 else
bcds(3 downto 0);
bcds_out_reg_next <= bcds when state = done else
bcds_out_reg;
bcd4 <= bcds_out_reg(19 downto 16);
bcd3 <= bcds_out_reg(15 downto 12);
bcd2 <= bcds_out_reg(11 downto 8);
bcd1 <= bcds_out_reg(7 downto 4);
bcd0 <= bcds_out_reg(3 downto 0);
end behaviour;
test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_bcd IS
END tb_bcd;
ARCHITECTURE behavior OF tb_bcd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT binary_bcd
PORT(
clk : IN std_logic;
reset : IN std_logic;
binary_in : IN std_logic_vector(15 downto 0);
bcd0 : OUT std_logic_vector(3 downto 0);
bcd1 : OUT std_logic_vector(3 downto 0);
bcd2 : OUT std_logic_vector(3 downto 0);
bcd3 : OUT std_logic_vector(3 downto 0);
bcd4 : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal binary_in : std_logic_vector(15 downto 0) := (others => '0');
--Outputs
signal bcd0 : std_logic_vector(3 downto 0);
signal bcd1 : std_logic_vector(3 downto 0);
signal bcd2 : std_logic_vector(3 downto 0);
signal bcd3 : std_logic_vector(3 downto 0);
signal bcd4 : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: binary_bcd PORT MAP (
clk => clk,
reset => reset,
binary_in => binary_in,
bcd0 => bcd0,
bcd1 => bcd1,
bcd2 => bcd2,
bcd3 => bcd3,
bcd4 => bcd4
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
reset <= '1';
wait for 100 ns;
reset <= '0';
binary_in <= "0000000000001111";
wait for 200 ns;
binary_in <= "0000000001001111";
wait for 200 ns;
binary_in <= "0000000001111111";
wait for 200 ns;
binary_in <= "0000111101001111";
wait for 2000 ns;
end process;
END;

Type of expression is ambiguous - "st_ulogic" or "bit" are two possible matches VHDL

Using the gezel software, I created a vhdl file from this fdl code:
dp delay_collatz_rev (
in start : ns(1) ; in x0 : ns(16) ;
out done : ns(1) ; out delay : ns(16))
{ reg r : ns(32) ;
reg d : ns(16) ;
reg stop : ns(1) ;
sig x : ns(32) ;
sig d0, dd : ns(16) ;
always { x = start ? x0 : r ;
r = x[0] ? x + (x >> 1) + 1 : x >> 1 ;
done = ( x == 1 ) | ( stop & ~start ) ;
stop = done ;
dd = 1 + x[0] ;
d0 = start ? 0 : d ;
d = done ? d0 : d0 + dd ;
delay = d ;
} }
But when I try to compile this code on the Quartus software, I am getting this error on line 124, which is "sig_10 <= unsigned('1') + unsigned(x(0));"
Error (10647): VHDL type inferencing error at delay_collatz_rev.vhd(124): type of expression is ambiguous - "std_ulogic" or "bit" are two possible matches
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
--use work.std_logic_arithext.all;
-- datapath entity
entity delay_collatz_rev is
port(
start : in std_logic;
x0 : in std_logic_vector(15 downto 0);
done : out std_logic;
delay : out std_logic_vector(15 downto 0);
RST : in std_logic;
CLK : in std_logic
);
end delay_collatz_rev;
architecture RTL of delay_collatz_rev is
-- signal declaration
signal r : std_logic_vector(31 downto 0);
signal r_wire : std_logic_vector(31 downto 0);
signal d : std_logic_vector(15 downto 0);
signal d_wire : std_logic_vector(15 downto 0);
signal stop : std_logic;
signal stop_wire : std_logic;
signal x : std_logic_vector(31 downto 0);
signal d0 : std_logic_vector(15 downto 0);
signal dd : std_logic_vector(15 downto 0);
signal sig_0 : std_logic_vector(31 downto 0);
signal sig_1 : std_logic_vector(31 downto 0);
signal sig_2 : std_logic_vector(31 downto 0);
signal sig_3 : std_logic_vector(31 downto 0);
signal sig_4 : std_logic_vector(31 downto 0);
signal sig_5 : std_logic_vector(31 downto 0);
signal sig_6 : std_logic;
signal sig_7 : std_logic;
signal sig_8 : std_logic;
signal sig_9 : std_logic;
signal sig_10 : std_logic;
signal sig_11 : std_logic_vector(15 downto 0);
signal sig_12 : std_logic_vector(15 downto 0);
signal sig_13 : std_logic_vector(15 downto 0);
signal done_int : std_logic;
signal delay_int : std_logic_vector(15 downto 0);
-- state register & states
begin
-- register updates
dpREG: process (CLK, RST)
begin
if (RST = '1') then
r <= (others => '0');
d <= (others => '0');
stop <= '0';
elsif CLK' event and CLK = '1' then
r <= r_wire;
d <= d_wire;
stop <= stop_wire;
end if;
end process dpREG;
-- combinational logics
dpCMB: process (r, d, stop, x, d0, dd, sig_0, sig_1, sig_2, sig_3
, sig_4, sig_5, sig_6, sig_7, sig_8, sig_9, sig_10, sig_11, sig_12, sig_13
, done_int, delay_int, start, x0)
begin
r_wire <= r;
d_wire <= d;
stop_wire <= stop;
x <= (others => '0');
d0 <= (others => '0');
dd <= (others => '0');
sig_0 <= (others => '0');
sig_1 <= (others => '0');
sig_2 <= (others => '0');
sig_3 <= (others => '0');
sig_4 <= (others => '0');
sig_5 <= (others => '0');
sig_6 <= '0';
sig_7 <= '0';
sig_8 <= '0';
sig_9 <= '0';
sig_10 <= '0';
sig_11 <= (others => '0');
sig_12 <= (others => '0');
sig_13 <= (others => '0');
done_int <= '0';
delay_int <= (others => '0');
done <= '0';
delay <= (others => '0');
if (start = '1') then
sig_0 <= std_logic_vector(resize(unsigned(x0), 32));
else
sig_0 <= r;
end if;
x <= sig_0;
sig_1 <= std_logic_vector(shift_right(unsigned(x), 1));
sig_2 <= std_logic_vector(unsigned(x) + unsigned(sig_1));
sig_3 <= std_logic_vector(unsigned(sig_2) + unsigned(std_logic_vector(to_unsigned(1, 32))));
sig_4 <= std_logic_vector(shift_right(unsigned(x), 1));
if (x(0) = '1') then
sig_5 <= sig_3;
else
sig_5 <= sig_4;
end if;
if (unsigned(x) = 1) then
sig_6 <= '1';
else
sig_6 <= '0';
end if;
sig_7 <= not start;
sig_8 <= stop and sig_7;
sig_9 <= sig_6 or sig_8;
done <= done_int;
sig_10 <= unsigned('1') + unsigned(x(0));
--sig_10 <= std_logic_unsigned(unsigned(unsigned('1')+unsigned(x(0))));
dd <= logic_zero_ext(sig_10, 16);
if (start = '1') then
sig_11 <= std_logic_vector(to_unsigned(0, 16));
else
sig_11 <= d;
end if;
d0 <= sig_11;
sig_12 <= std_logic_vector(unsigned(d0) + unsigned(dd));
if (done_int = '1') then
sig_13 <= d0;
else
sig_13 <= sig_12;
end if;
delay <= delay_int;
done_int <= sig_9;
delay_int <= d;
r_wire <= sig_5;
stop_wire <= done_int;
d_wire <= sig_13;
end process dpCMB;
end RTL;
I am pretty new with Gezel and VHDL, what am I missing?
The Gezel to VHDL generator does not create valid VHDL code, since the used packages does not support addition with target in std_logic as in sig_10 <= unsigned('1') + unsigned(x(0));.
I guess that the problem is due to selection of a single bit in x as x[0], and maybe you can work around this if creating a temporary one bit for x[0], and the assign this with x[0] before making the addition:
sig temp_x_0 : ns(1) ;
...
temp_x_0 = x[0];
dd = 1 + temp_x_0;
But I must admit that I am not that much into Gezel.

FSM model of FIR filter

I want to make a FSM model of FIR, for that I need to write FIR calculation code line in FSM implementation.
Here is the actual and correct code for FIR
entity fir_4tap is
port( Clk : in std_logic; --clock signal
Clk_fast : in std_logic;
-- Xin : in signed(7 downto 0); --input signal
bit_in : in std_logic;
bit_out : out std_logic;
Yout : out signed(15 downto 0) --filter output
);
end fir_4tap;
architecture Behavioral of fir_4tap is
signal add_out3 : signed(15 downto 0) := (others => '0');
signal index : unsigned(2 downto 0) := (others =>'0');
signal counter : unsigned(3 downto 0) := (others => '0');
signal p : unsigned(1 downto 0) := (others => '0');
signal k : unsigned(1 downto 0) := (others => '0');
signal j : unsigned(1 downto 0) := (others => '0');
type array_signed is array(8 downto 0) of signed(7 downto 0);
signal z : array_signed := (others => "00000000");
type array_signed1 is array(3 downto 0) of signed(7 downto 0);
signal H : array_signed1 := (others => "00000000");
signal Xin : array_signed1 := (others => "00000000");
begin
z(0) <= to_signed(-3,8);
z(1) <= to_signed(1,8);
z(2) <= to_signed(0,8);
z(3) <= to_signed(-2,8);
z(4) <= to_signed(-1,8);
z(5) <= to_signed(4,8);
z(6) <= to_signed(-5,8);
z(7) <= to_signed(6,8);
z(8) <= to_signed(0,8);
H(0) <= to_signed(-2,8);
H(1) <= to_signed(-1,8);
H(2) <= to_signed(3,8);
H(3) <= to_signed(4,8);
process (clk)
begin
if (rising_edge(Clk)) then
index <= index +1;
if (index = "111") then
Xin(to_integer(p)) <= z(to_integer(counter)); k <= p;
p <= p + 1;
***-- This part of the code has problem, I want to write the line which is summing --up for add_out3 in a for loop.***
add_out3 <= (others => '0');
add_out3 <= Xin(to_integer(k))*H(to_integer(j)) + Xin(to_integer(k-1))*H(to_integer(j+1)) + Xin(to_integer(k-2))*H(to_integer(j+2)) + Xin(to_integer(k-3))*H(to_integer(j+3));
Yout <= add_out3;
end if;
end if;
end process;
end Behavioral;
Now Below is the FSM implementation try by me but not getting the same out sample as input can somebody tell me what could be the problem in the code?
----------------FSM implementation of the FIR filter ----------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity test is
port( Clk : in std_logic; --clock signal
Clk_fast : in std_logic;
bit_in : in std_logic;
bit_out : out std_logic;
Yout : out signed(15 downto 0) --filter output
);
end test;
architecture Behavioral of test is
signal data_buffer : signed(7 downto 0) := (others => '0');
signal index : unsigned(2 downto 0) := (others =>'0');
signal counter : unsigned(3 downto 0) := (others => '0');
type array_signed is array(8 downto 0) of signed(7 downto 0);
signal z : array_signed := (others => "00000000");
type array_signed1 is array(3 downto 0) of signed(7 downto 0);
signal H : array_signed1 := (others => "00000000");
signal input : signed(7 downto 0) := (others => '0');
type MULT_TYPE is array(3 downto 0) of signed(15 downto 0);
signal MULT_array : MULT_TYPE := (others => "0000000000000000");
type ADD_TYPE is array(3 downto 0) of signed(15 downto 0);
signal ADD_array : ADD_TYPE := (others => "0000000000000000");
constant ZERO : signed(15 downto 0) := (others => '0');
type state_type is (s0,s1,s2,s3); --type of state machine.
signal current_s : state_type := s0; --current and next state declaration.
signal next_s : state_type := s0;
signal reset : std_logic := '0';
signal go : std_logic := '0';
signal change_state : std_logic := '0' ;
signal counter_FSM_monitor : unsigned( 6 downto 0) := "0000000";
begin
z(0) <= to_signed(-3,8);
z(1) <= to_signed(1,8);
z(2) <= to_signed(0,8);
z(3) <= to_signed(-2,8);
z(4) <= to_signed(-1,8);
z(5) <= to_signed(4,8);
z(6) <= to_signed(-5,8);
z(7) <= to_signed(6,8);
z(8) <= to_signed(0,8);
H(0) <= to_signed(-2,8);
H(1) <= to_signed(-1,8);
H(2) <= to_signed(3,8);
H(3) <= to_signed(4,8);
process (Clk) is
begin
if falling_edge(Clk) then
data_buffer(to_integer(index)) <= bit_in;
index <= index +1;
if (index = "111") then
input <= z(to_integer(counter));
counter <= counter + 1;
if(counter = "1000") then
counter <= "0000";
end if;
end if;
end if;
end process;
process (clk_fast)
begin
if (falling_edge(clk_fast)) then
counter_FSM_monitor <= counter_FSM_monitor + 1;
if( to_integer(counter_FSM_monitor) = 76) then
counter_FSM_monitor <= "0000000";
end if;
case change_state is
when '1' =>
current_s <= next_s; --state change.
when '0' => --current_s <= s0;
when others =>
end case;
end if;
end process;
Process(current_s,input)
begin
if ( to_integer(counter_FSM_monitor) < 64 ) then
-- waiting for the Input
elsif (to_integer(counter_FSM_monitor) >= 64 and to_integer(counter_FSM_monitor) < 76) then
---------------------------------------------- FSM ----------------------------------------
case current_s is
when s0 =>
mult_array(0) <= input*H(3);
ADD_array(0) <= ZERO + mult_array(0);
next_s <= s1;
change_state <= '1';
when s1 =>
mult_array(1) <= input*H(2);
ADD_array(1) <= mult_array(1) + ADD_array(0);
next_s <= s2;
change_state <= '1';
when s2 =>
mult_array(2) <= input*H(1);
ADD_array(2) <= mult_array(2) + ADD_array(1);
next_s <= s3;
change_state <= '1';
when s3 =>
mult_array(3) <= input*H(0);
ADD_array(3) <= mult_array(3) + ADD_array(2);
Yout <= ADD_array(3);
next_s <= s0;
change_state <= '1';
when others =>
next_s <= s0;-- never comes here
change_state <= '1';
end case;
---------------------------------------------- FSM ----------------------------------------
end if;
end process;
end Behavioral;
How ever I am not able to receive the same output which I received by the first code.
FSM code gives the correct output for the first out but from the second out sample it gives wrong result.Can somebody tell me what I am doing wrong ?
This answer is for the initial version of the question but Now question has been changed.
Made add_out3 a variable instead of a signal.
for i in 0 to 3 loop
add_out3 := add_out3 + Xin(k-i)*H(i);
end loop;
Did the above changes in the for loop It works fine.
So the code in my question is a correct code for FIR also, works smoothly.
Learnt that one needs to be very careful while using signal or variables. All the signals get a new value at the same time i.e at the end of clock period, while in variables values gets updated as assigned within a process. Tried to run the simulation step by step and figured out the problem.

Resources