Type of expression is ambiguous - "st_ulogic" or "bit" are two possible matches VHDL - 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.

Related

Flags for ALU in VHDL not updating when running simulation

So far everything works as intended except for the Cout (carryout) and V (overflow) when I simulate in the testbench. I get constant Us when performing addition and subtraction. I performed some of the calculations I'm testing by hand so I know which should have a carry value and overflow value.
entity ALU is
Port ( Cin : in STD_LOGIC_VECTOR ( 0 downto 0);
ALUCntrl : in STD_LOGIC_VECTOR ( 3 downto 0);
A, B : in STD_LOGIC_VECTOR (31 downto 0);
ALUout : out STD_LOGIC_VECTOR (31 downto 0);
Cout, Z, V : out STD_LOGIC );
end ALU;
architecture Behavioral of ALU is
SIGNAL result : STD_LOGIC_VECTOR (32 downto 0);
SIGNAL bCout, bZ, bV : STD_LOGIC;
begin
WITH ALUCntrl SELECT
result(31 downto 0) <= A and B when "0000",
A or B when "0001",
A xor B when "0011",
std_logic_vector(unsigned(A) + unsigned(B) + unsigned(Cin)) WHEN "0010",
std_logic_vector(unsigned(A) - unsigned(B)) WHEN "0110",
A xnor B WHEN "1100",
A xnor B WHEN "1111",
"00000000000000000000000000000000" WHEN OTHERS;
WITH result(31 downto 0) SELECT
bZ <= '1' WHEN "00000000000000000000000000000000",
'0' WHEN OTHERS;
WITH ALUCntrl SELECT
bCout <= result(32) WHEN "0010",
result(32) WHEN "0110",
'0' WHEN OTHERS;
PROCESS(ALUCntrl)
BEGIN
CASE ALUCntrl IS
WHEN "0010" =>-- Addition Overflow
IF ((A(31) = '1') and (B(31) = '1') and (result(31) = '0')) THEN
bV <= '1';
ELSIF ((A(31) = '0') and (B(31) = '0') and (result(31) = '1')) THEN
bV <= '1';
ELSE
bV <= '0';
END IF;
WHEN "0110" => -- Subtraction overflow
IF ((A(31) = '0') and (B(31) ='1') and (result(31) = '1')) THEN
bV <= '1';
ELSIF ((A(31) = '1') and (B(31) = '0') and (result(31) = '0')) THEN
bV <= '1';
ELSE
bV <= '0';
END IF;
WHEN OTHERS =>
bV <= '0';
END CASE;
END PROCESS;
ALUout <= result(31 downto 0);
Cout <= bCout;
Z <= bZ;
V <= bV;
end Behavioral;
TEST-BENCH
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ALU_tb is
-- Port ( );
end ALU_tb;
architecture Behavioral of ALU_tb is
-- INPUTS
signal Cin : STD_LOGIC_VECTOR ( 0 downto 0);
signal A, B : STD_LOGIC_VECTOR (31 downto 0);
signal ALUCntrl : STD_LOGIC_VECTOR ( 3 downto 0);
-- OUTPUTS
signal ALUout : STD_LOGIC_VECTOR (31 downto 0);
signal Cout, Z, V : STD_LOGIC;
component ALU is
port(
Cin : in STD_LOGIC_VECTOR ( 0 downto 0);
A, B : in STD_LOGIC_VECTOR (31 downto 0);
ALUCntrl : in STD_LOGIC_VECTOR ( 3 downto 0);
ALUout : out STD_LOGIC_VECTOR (31 downto 0);
Cout, Z, V : out STD_LOGIC );
end component ALU;
begin
design_ALU: ALU
port map(
Cin => Cin,
A => A,
B => B,
ALUCntrl => ALUCntrl,
ALUout => ALUout,
Cout => Cout,
Z => Z,
V => V
);
tb : PROCESS
BEGIN
ALUCntrl <= "0000"; -- AND
Cin <= "00";
A <= "11111111111111111111111111111111";
B <= "00000000000000000000000000000000";
wait for 250ns;
ALUCntrl <= "0001"; -- OR
A <= "10011000100110001001100010011000";
B <= "10001001100010011000100110001001";
wait for 250ns;
ALUCntrl <= "0011"; -- XOR
A <= "00000001000000010000000100000001";
B <= "00010000000100000001000000010000";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "00000000000000000000000000000001";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "01100011100010010111010101001111";
B <= "10101101010101100010010011100110";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
Cin <= "01";
A <= "00000000000000000000000000000001";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "01100011100010010111010101001111";
B <= "10101101010101100010010011100110";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "11111111111111111111111111111111";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "00000000000000000000000000000000";
B <= "00000000000000000000000000000001";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "11111001011010000100011110000011";
B <= "11111001100110001101010101100010";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "10000000000000000000000000000000";
B <= "00000001000000000000000000000000";
wait for 250ns;
ALUCntrl <= "1100"; -- NOR
A <= "10011010101111001101111011011111";
B <= "10011010101111001101111011111101";
wait for 250ns;
ALUCntrl <= "1111"; -- XNOR
A <= "10001001101111001101111000110100";
B <= "11000101001110111101011010000111";
wait;
END PROCESS tb;
end Behavioral;

SDRAM Controller in VHDL

I have to develop a SDRAM controller for a class project in VHDL. But this is my first time working with VHDL, that has a very important learning curve.
I have downloaded a SDRAM controller from github (https://github.com/christianmiyoshi/SDRAM_Controller_VHDL/blob/master/sdram_controller.vhd) and I am trying to complete it.
I am trying to write a data in an address and later read it, but I cant read a single data. I dont know if my problem is in the writing or in the reading process.
Can anybody help me, please?
Thank you all!
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ram_controller is
port(
clk : in std_logic;
reset: in std_logic;
refresh: in std_logic;
read_write_enable: in std_logic;
write_n: in std_logic;
address: in std_logic_vector(21 downto 0);
data_in: in std_logic_vector(15 downto 0);
dqmu: in std_logic;
dqml: in std_logic;
ready: out std_logic;
done: out std_logic;
data_out: out std_logic_vector(15 downto 0);
single_burst: in std_logic; --0 single y 1 burst
SDRAM_CKE: out std_logic;
SDRAM_CS_N: out std_logic;
SDRAM_RAS_N: out std_logic;
SDRAM_CAS_N: out std_logic;
SDRAM_WE_N: out std_logic;
SDRAM_BA: out std_logic_vector(1 downto 0);
SDRAM_SA: out std_logic_vector(11 downto 0);
SDRAM_DQ: inout std_logic_vector(15 downto 0);
SDRAM_DQM: out std_logic_vector(1 downto 0)
);
end entity;
architecture behavior of ram_controller is
type state_type is (init_ckeLow, init_stableClock, init_wait, init_nopCommand, init_prechargeAll, init_refresh_1, init_mode, init_refresh_2, idle, refresh_state, activate_row, activate_rcd, read_write, ras1, ras2, precharge);
signal state: state_type := init_ckeLow;
signal ticks: std_logic_vector(7 downto 0) := (others => '0');
signal ticks_ref: integer := 0;
signal ticks_ref_refresh: integer := 0;
constant burstMode: std_logic := '0';
constant casLatency: std_logic_vector(2 downto 0) := "010";
constant burstType: std_logic := '0';
constant burstLength: std_logic_vector(2 downto 0) := "000";
--signal highz_output: std_logic:= '0';
constant MODE_REG: std_logic_vector(11 downto 0) := "00" & burstMode & "00" & casLatency & burstType & burstLength;
constant MODE_REG_BURST: std_logic_vector(11 downto 0) := "000000100111";
signal command: std_logic_vector(3 downto 0);
signal row: std_logic_vector(11 downto 0);
signal column: std_logic_vector(7 downto 0);
signal bank: std_logic_vector(1 downto 0);
signal sd_busdir_x: std_logic:='0';
-- Command truth table
-- CS_N, RAS_N, CAS_N, WE_N
constant CMD_ACTIVATE: std_logic_vector(3 downto 0) := "0011";
constant CMD_PRECHARGE: std_logic_vector(3 downto 0) := "0010";
constant CMD_WRITE: std_logic_vector(3 downto 0) := "0100";
constant CMD_READ: std_logic_vector(3 downto 0) := "0101";
constant CMD_MODE: std_logic_vector(3 downto 0) := "0000";
constant CMD_NOP: std_logic_vector(3 downto 0) := "0111";
constant CMD_REFRESH: std_logic_vector(3 downto 0) := "0001";
signal address_buffer: std_logic_vector(21 downto 0) := (others => '0');
signal data_in_buffer: std_logic_vector(15 downto 0) := (others => '0');
signal dqu_buffer: std_logic := '0';
signal dql_buffer: std_logic := '0';
signal ready_buffer: std_logic := '0';
signal done_buffer: std_logic := '0';
signal data_out_buffer: std_logic_vector(15 downto 0) := (others => '0');
signal CKE: std_logic;
signal CS_N: std_logic;
signal RAS_N: std_logic;
signal CAS_N: std_logic;
signal WE_N: std_logic;
signal BA: std_logic_vector(1 downto 0);
signal SA: std_logic_vector(11 downto 0);
signal DQ: std_logic_vector(15 downto 0);
signal DQM: std_logic_vector(1 downto 0);
signal contador : std_logic_vector(15 downto 0) := x"0000";
signal modo: std_logic := '0';
begin
(CS_N, RAS_N, CAS_N, WE_N) <= command;
SDRAM_CKE <= CKE;
SDRAM_CS_N <= CS_N;
SDRAM_RAS_N <= RAS_N;
SDRAM_CAS_N <= CAS_N;
SDRAM_WE_N <= WE_N;
SDRAM_BA <= BA;
SDRAM_SA <= SA;
--SDRAM_DQ <= DQ;
SDRAM_DQM <= DQM;
--SA <= address_buffer;
SDRAM_DQ <= data_in_buffer when sd_busdir_x = '1' else (others => 'Z');
DQM <= dqu_buffer & dql_buffer;
ready <= ready_buffer;
done <= done_buffer;
data_out <= data_out_buffer;
bank <= address(21 downto 20);
row <= address(19 downto 8);
column <= address(7 downto 0);
process(clk, reset)
begin
if reset = '0' then
state <= init_ckeLow;
ticks_ref <= 0;
elsif rising_edge(clk) then
if ticks_ref /= 0 then
ticks_ref <= ticks_ref - 1;
else
-- Micron datasheet instructions
-- Frequency = 100 Mhz => period of 10ns
-- 1: Apply Vdd and Vddq simultaneously
case state is
when init_ckeLow =>
-- 2: Assert and hold CKE ant LVTTL logic low
ticks_ref <= 10;
CKE <= '0';
state <= init_stableClock;
when init_stableClock =>
-- 3: Provide stable clock
ticks_ref <= 10;
state <= init_wait;
when init_wait=>
-- 4: Wait at least 100us
-- 5: bring cke high at some point of the period
-- with command inhibit or nop
--ticks_ref <= 10000;
ticks_ref <= 2; -- debugadd
state <= init_nopCommand;
when init_nopCommand =>
--ticks_ref <= 10000;
ticks_ref <= 2; -- debug
CKE <= '1';
command <= CMD_NOP;
state <= init_prechargeAll;
when init_prechargeAll =>
-- 6: perform precharge all
-- 7: wait at leas t_RP
command <= CMD_PRECHARGE;
BA <= "00";
SA(10) <= '1'; -- all banks
ticks_ref <= 2;
ticks_ref_refresh <= 8;
state <= init_refresh_1;
when init_refresh_1 =>
-- auto refresj period: < 64 ns
if ticks_ref_refresh = 0 then
state <= init_mode;
else
ticks_ref_refresh <= ticks_ref_refresh - 1;
command <= CMD_REFRESH;
ticks_ref <= 7;
end if;
when init_mode =>
command <= CMD_MODE;
if single_burst = '0' then
SA <= MODE_REG;
modo <= '0';
else
SA <= MODE_REG_BURST;
modo <= '1';
end if;
BA <= "00";
ticks_ref <= 2;
ticks_ref_refresh <= 8;
state <= init_refresh_2;
when init_refresh_2 =>
if ticks_ref_refresh = 0 then
state <= idle;
--done_buffer <= '1';
else
ticks_ref_refresh <= ticks_ref_refresh - 1;
command <= CMD_REFRESH;
ticks_ref <= 7;
end if;
when idle =>
done_buffer <= '0';
contador <= (others => '0');
if read_write_enable = '1' then
-- tras: active to precharge: 45 ns min, 120000ns max
state <= activate_row;
command <= CMD_ACTIVATE;
SA <= row;
BA <= bank;
--done_buffer <= '0';
elsif refresh = '1' then
state <= refresh_state;
command <= CMD_REFRESH;
ticks_ref <= 7;
--done_buffer <= '0';
end if;
when refresh_state =>
state <= idle;
--done_buffer <= '1';
when activate_row =>
--trcd 20 ns
command <= CMD_NOP;
state <= activate_rcd;
data_in_buffer <= data_in;
ticks_ref <= 1;
when activate_rcd =>
-- trcs = 20ns min
state <=read_write;
SA <= "0000" & column;
if write_n = '0' then
command <= CMD_WRITE;
dqu_buffer <= dqmu;
dql_buffer <= dqml;
sd_busdir_x <= '1';
else
command <= CMD_READ;
end if;
when read_write =>
--command <= CMD_NOP;
state <= ras1;
--if modo='0' then
--sd_busdir_x <= '0';
--end if;
when ras1 =>
state <= ras2;
command <= CMD_NOP;
when ras2 =>
-- trp = 20ns min
if modo='1' and contador <= x"00FF" then
data_in_buffer <= data_in;
state <= ras2;
contador <= contador +1;
else
contador <= (others => '0');
state <= precharge;
sd_busdir_x <= '0';
command <= CMD_PRECHARGE;
SA(10) <= '1';
data_out_buffer <= SDRAM_DQ;
ticks_ref <= 2;
end if;
when precharge =>
state <= idle;
done_buffer <= '1';
ticks_ref <= 1;
end case;
end if;
end if;
end process;
end architecture;
[enter image description here][1]
[1]: https://i.stack.imgur.com/CaqqL.png

Simple VHDL ALU will not show inputs or overflow in the waveform

I'm supposed to write up a 16-bit ALU. My professor wants us to try and code the adder and sub of the ALU with a
signal tmp : std_logic_vector(16 downto 0); and then in the case for the select input s we put:
tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
After experimenting with it for a while, my waveform only showed the inputs' values as UUUUUUUUUUUUUUUU. Even after I had commented out the conv_std_logic_vector(...) stuff.
Is there a simple explanation as to why my inputs aren't showing up in the waveform?
Here is my code:
-- 16-Bit ALU
-- By: Logan Jordon
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
--use ieee.std_logic_arith.all;
 
entity alu16 is
port (
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end entity alu16;
architecture beh of alu16 is
signal tmp : std_logic_vector(16 downto 0);
signal add_overflow : std_logic;
signal sub_overflow : std_logic;
begin
-- PROCESS
process(a, b, add_overflow, sub_overflow)
begin
case s is
--ADD
when "00" =>
--tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
tmp <= a + b;
overflow <= add_overflow;
--SUB
when "01" =>
--tmp <= conv_std_logic_vector(conv_integer(a) - conv_integer(b), 17);
tmp <= a - b;
overflow <= sub_overflow;
--AND
when "10" =>
tmp <= '0' & a AND b;
overflow <= '0';
--OR
when "11" =>
tmp <= '0' & a OR b;
overflow <= '0';
when others =>
tmp <= "00000000000000000";
end case;
--One-Bitters
if a > b then
gt <= '1';
lt <= '0';
eq <= '0';
elsif a < b then
lt <= '1';
gt <= '0';
eq <= '0';
elsif a = b then
eq <= '1';
lt <= '0';
gt <= '0';
end if;
end process;
--OUTPUTS
cout <= tmp(16);
r <= tmp(15 downto 0);
add_overflow <= '1' when (a(15) = b(15)) and (a(15) /= tmp(15))
else '0';
sub_overflow <= '1' when (a(15) = NOT b(15)) and (a(15) /= tmp(15))
else '0';
end beh;
EDIT: In the case that it might be my test bench, here's the code for my testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
entity alu16_tb is
end alu16_tb;
architecture behavior of alu16_tb is
component ALU16
port(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end component;
-- Signals to interface with the UUT
-- Set each of the input vectors to unique values to avoid
-- needing a process to drive them below
signal a : std_logic_vector(15 downto 0) := "0000000000000000";
signal b : std_logic_vector(15 downto 0) := "0000000000000000";
signal s : std_logic_vector(1 downto 0) := "00";
signal r : std_logic_vector(15 downto 0):= "0000000000000000";
signal cout : std_logic := '0';
signal lt : std_logic := '0';
signal gt : std_logic := '0';
signal eq : std_logic := '0';
signal overflow : std_logic := '0';
constant tick : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut : ALU16 port map (
a => a,
b => b,
s => s,
r => r,
cout => cout,
lt => lt,
gt => gt,
eq => eq,
overflow => overflow
);
-- Drive selector bits
drive_s : process
begin
a <= "0000000000000001";
b <= "0000000000000010";
wait for (tick*2);
s <= "00";
wait for (tick*2);
s <= "01";
wait for (tick*2);
s <= "10";
wait for (tick*2);
s <= "11";
end process drive_s;
end;

My VHDL ALU code behave awkward

I have a problem with VHDL ALU code. I have to make simple ALU with 4 operations with 4-bit operands. I implemented these operations correctly and they work well. For executing I use E2LP board. For choosing the operation I selected 4 JOY buttons,one for each operation. Problem is that when I press button to execute operation and depress it I want result to stay on LEDs while I don't select any other operation, but that's not happening. For first 5 LEDs this works fine, but upper 3 not.This only works for one operation. My simulation results are correct. Here is code an schema of project.Thank you in advance.
---------------------------------------------------------------------------------- Control logic
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Port ( --clk : in STD_LOGIC;
in_saberi : in STD_LOGIC;
in_mnozi : in STD_LOGIC;
in_ili : in STD_LOGIC;
in_rotiraj : in STD_LOGIC;
out_saberi : out STD_LOGIC;
out_mnozi : out STD_LOGIC;
out_ili : out STD_LOGIC;
out_rotiraj : out STD_LOGIC);
end upravljanje;
architecture Behavioral of upravljanje is
signal tmps : std_logic := '1';
signal tmpm : std_logic := '1';
signal tmpi : std_logic := '1';
signal tmpr : std_logic := '1';
begin
logika : process(in_saberi,in_mnozi,in_ili,in_rotiraj)
begin
if (in_saberi='0' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_mnozi='0' and in_saberi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='0' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='0') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= tmps;
tmpm <= tmpm;
tmpi <= tmpi;
tmpr <= tmpr;
else
tmps <= '1';
tmpm <= '1';
tmpi <= '1';
tmpr <= '1';
end if;
end process logika;
out_saberi <= tmps;
out_mnozi <= tmpm;
out_ili <= tmpi;
out_rotiraj <= tmpr;
end Behavioral;
--------------------------------------------------------------------------
-- this is for operation add
entity sabirac is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
saberi : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end sabirac;
architecture Behavioral of sabirac is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
sabiranje : process(clk,saberi)
begin
if (saberi='0') then
tmp(0) <= data1(0) xor data2(0);
c(0) <= data1(0) and data2(0);
tmp(1) <= data1(1) xor data2(1) xor c(0);
c(1) <= (data1(1) and data2(1)) or (data1(1) and c(0)) or (data2(1) and c(0));
tmp(2) <= data1(2) xor data2(2) xor c(1);
c(2) <= (data1(2) and data2(2)) or (data1(2) and c(1)) or (data2(2) and c(1));
tmp(3) <= data1(3) xor data2(3) xor c(2);
if(data1(3) = data2(3)) then
c(3) <= (data1(3) and data2(3)) or (data1(3) and c(2)) or (data2(3) and c(2));
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
else
c(3) <= data1(3) xor data2(3) xor c(2);
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
end if;
else
tmp <= "ZZZZZZZZ";
end if;
end process sabiranje;
result <= tmp;
end Behavioral;
-----------------------------------------------------------------------------
entity mul is
Port (
clk : in STD_LOGIC;
pomnozi : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end mul;
architecture Behavioral of mul is
begin
mnozenje : process (clk,pomnozi)
begin
if (pomnozi='0') then
result <= std_logic_vector(signed(data1) * signed(data2));
else
result <= "ZZZZZZZZ";
end if;
end process mnozenje;
end Behavioral;
--------------------------------------------------------------------------
entity rotate is
Port ( clk : in STD_LOGIC;
rotiraj : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end rotate;
architecture Behavioral of rotate is
signal tmp : std_logic_vector (3 downto 0) := "0000";
signal tmp2 : std_logic_vector (7 downto 0) := "00000000";
begin
rotacija : process(clk,rotiraj)
begin
if (rotiraj='0') then
tmp <= std_logic_vector(rotate_left(unsigned(data1),to_integer(unsigned(data2))));
tmp2(0) <= tmp(0);
tmp2(1) <= tmp(1);
tmp2(2) <= tmp(2);
tmp2(3) <= tmp(3);
tmp2(4) <= '0';
tmp2(5) <= '0';
tmp2(6) <= '0';
tmp2(7) <= '0';
else
tmp2 <= "ZZZZZZZZ";
end if;
end process rotacija;
result <= tmp2;
end Behavioral;
--------------------------------------------------------------------------
-- Logic OR operation
entity logicko_ILI is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
logili : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end logicko_ILI;
architecture Behavioral of logicko_ILI is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
logicko : process(clk,logili)
begin
if (logili = '0') then
tmp(0) <= data1(0) or data2(0);
tmp(1) <= data1(1) or data2(1);
tmp(2) <= data1(2) or data2(2);
tmp(3) <= data1(3) or data2(3);
tmp(4) <= '0';
tmp(5) <= '1';
tmp(6) <= '1';
tmp(7) <= '1';
else
tmp <= "ZZZZZZZZ";
end if;
end process logicko;
result <= tmp;
end Behavioral;
I think you should even use your clk and reset signals in process. Your design is completely asynchron! This is a very bad idea.
A synchron process with asynchron reset look like this:
test : process (clk,reset)
begin
if (reset) then
c = 0;
elsif (rising_edge(clk)) then
c = a + b;
end if;
end process:
None of your sensitivity lists are correct. This does not comply with IEEE standard on syntesizable RTL. It poses a a high risk of getting synthesis results that are different from your simulation results.
line: 24 Incomplete sensitivity list. Missing signals: tmpm, tmps, tmpr, tmpi
line: 86 Incomplete sensitivity list. Missing signals: data1, data2, c
line: 137 Incomplete sensitivity list. Missing signals: data1, data2
line: 166 Incomplete sensitivity list. Missing signals: tmp, data1, data2
line: 205 Incomplete sensitivity list. Missing signals: data1, data2,
(line numbers might be slightly off because I had to add use/library clauses for ieee.std_logic_1164)
Please check your synthesis results for warnings, or use a VHDL code checker before your synthesize.

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