VHDL Mysterious Red Waves - vhdl

I'm building a "package sorter" which basically takes a weight, and adds it to a specific group based on that weight, and keeps track of how many weights (aka packages) are in each group using a simple counter. However, when running my test bench, I'm encountering weird red waves that shouldn't really be there:
Now I have read that these could mainly result from assigning the same signal a value from two different locations, however I've been failing to find the culprit and the deadline is nearing. Here is my code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity packageSorter is
port (clk,reset: in std_logic;
weight: in std_logic_vector (11 downto 0);
grp1: out std_logic_vector(7 downto 0);
grp2: out std_logic_vector(7 downto 0);
grp3: out std_logic_vector(7 downto 0);
grp4: out std_logic_vector(7 downto 0);
grp5: out std_logic_vector(7 downto 0);
grp6: out std_logic_vector(7 downto 0);
currentGrp: out std_logic_vector(2 downto 0)) ;
end packageSorter;
architecture beh of packageSorter is
signal count1 : integer range 0 to 256;
signal count2 : integer range 0 to 256;
signal count3 : integer range 0 to 256;
signal count4 : integer range 0 to 256;
signal count5 : integer range 0 to 256;
signal count6 : integer range 0 to 256;
signal lastWeight : std_logic_vector (11 downto 0);
signal currentWeight : std_logic_vector (11 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if(reset = '1') then
count1 <= 0;
count2 <= 0;
count3 <= 0;
count4 <= 0;
count5 <= 0;
count6 <= 0;
lastWeight <= "000000000000";
currentWeight <= Weight; -- intermediate signal equal to input
end if;
if to_integer(unsigned(lastWeight)) = 0 then --IF LAST WEIGHT WAS 0
if to_integer(unsigned(weight)) = 0 then
currentGrp <= std_logic_vector(to_unsigned(0,3));
elsif to_integer(unsigned(weight)) >= 1 and to_integer(unsigned(weight)) <= 200 then --group 1
count1 <= (count1 + 1);
currentGrp <= std_logic_vector(to_unsigned(1,3));
lastWeight <= weight;
elsif to_integer(unsigned(weight)) >= 201 and to_integer(unsigned(weight)) <= 500 then --group 2
count2 <= (count2 + 1);
currentGrp <= std_logic_vector(to_unsigned(2,3));
lastWeight <= weight;
elsif to_integer(unsigned(weight)) >= 501 and to_integer(unsigned(weight)) <= 800 then --group 3
count3 <= (count3 + 1);
currentGrp <= std_logic_vector(to_unsigned(3,3));
lastWeight <= weight;
elsif to_integer(unsigned(weight)) >= 801 and to_integer(unsigned(weight)) <= 1000 then --group 4
count4 <= (count4 + 1);
currentGrp <= std_logic_vector(to_unsigned(4,3));
lastWeight <= weight;
elsif to_integer(unsigned(weight)) >= 1001 and to_integer(unsigned(weight)) <= 2000 then --group 5
count5 <= (count5 + 1);
currentGrp <= std_logic_vector(to_unsigned(5,3));
lastWeight <= weight;
elsif to_integer(unsigned(weight)) >= 2000 then --group 6
count6 <= (count6 + 1);
currentGrp <= std_logic_vector(to_unsigned(6,3));
lastWeight <= weight;
end if;
elsif to_integer(unsigned(lastWeight)) /= 0 then
lastWeight <= std_logic_vector(unsigned(Weight) + unsigned(lastWeight));
currentWeight <= lastWeight; --currentWeight is whatever the input weight is
if to_integer(unsigned(currentWeight)) = 0 then
currentGrp <= std_logic_vector(to_unsigned(0,3));
lastWeight <= "000000000000";
elsif to_integer(unsigned(currentWeight)) >= 1 and to_integer(unsigned(currentWeight)) <= 200 then --group 1
currentGrp <= std_logic_vector(to_unsigned(1,3));
elsif to_integer(unsigned(currentWeight)) >= 201 and to_integer(unsigned(currentWeight)) <=500 then --group 2
currentGrp <= std_logic_vector(to_unsigned(2,3));
elsif to_integer(unsigned(currentWeight)) >= 501 and to_integer(unsigned(currentWeight)) <= 800 then --group 3
currentGrp <= std_logic_vector(to_unsigned(3,3));
elsif to_integer(unsigned(currentWeight)) >= 801 and to_integer(unsigned(currentWeight)) <= 1000 then --group 4
currentGrp <= std_logic_vector(to_unsigned(4,3));
elsif to_integer(unsigned(currentWeight)) >= 1001 and to_integer(unsigned(currentWeight)) <= 2000 then --group 5
currentGrp <= std_logic_vector(to_unsigned(5,3));
elsif to_integer(unsigned(currentWeight)) >= 2001 then --group 6
currentGrp <= std_logic_vector(to_unsigned(6,3));
end if;
end if;
end if;
end process;
grp1 <= std_logic_vector(to_unsigned(count1,8));
grp2 <= std_logic_vector(to_unsigned(count2,8));
grp3 <= std_logic_vector(to_unsigned(count3,8));
grp4 <= std_logic_vector(to_unsigned(count4,8));
grp5 <= std_logic_vector(to_unsigned(count5,8));
grp6 <= std_logic_vector(to_unsigned(count6,8));
end beh;
It is definitely worth noting that even the clock signal (Which triggers the counter on a rising edge) goes red and corrupt as shown in the first wave, despite not having any assignments to it. I have included my test bench as well as I'm not sure if the issue could be stemming from there but I doubt that is the case
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity packageSorter_TB is
end packageSorter_TB;
architecture tb of packageSorter_TB is
component packageSorter
port (clk,reset: in std_logic;
weight: in std_logic_vector (11 downto 0);
grp1: out std_logic_vector(7 downto 0);
grp2: out std_logic_vector(7 downto 0);
grp3: out std_logic_vector(7 downto 0);
grp4: out std_logic_vector(7 downto 0);
grp5: out std_logic_vector(7 downto 0);
grp6: out std_logic_vector(7 downto 0);
currentGrp: out std_logic_vector(2 downto 0));
end component;
signal TB_clk: std_logic := '0';
signal TB_reset : std_logic := '0';
signal TB_weight : std_logic_vector (11 downto 0) := "000000000000";
signal TB_grp1, TB_grp2, TB_grp3, TB_grp4, TB_grp5, TB_grp6 : std_logic_vector(7 downto 0) := "00000000";
signal TB_currentGrp: std_logic_vector(2 downto 0) := "000";
begin
UUT : packageSorter port map ( clk => TB_clk, reset => TB_reset, weight => TB_weight, grp1 => TB_grp1, grp2 => TB_grp2, grp3 => TB_grp3,
grp4 => TB_grp4, grp5 => TB_grp5, grp6 => TB_grp6, currentGrp => TB_currentGrp);
TB_clk <= '0' after 10 ns;
TB_clk <= '1' after 20 ns;
TB_weight <= "000011111010" after 30 ns; --250
TB_clk <= '0' after 40 ns, '1' after 50 ns;
TB_weight <= "000000000000" after 60 ns;
TB_clk <= '0' after 70 ns, '1' after 80 ns;
TB_weight <= "000111111010" after 90 ns; --506
-- TB_clk <= '0' after 35ns;
-- TB_clk <= '1' after 40ns;
-- TB_weight <= "000100000000" after 40ns;
-- TB_clk <= '0' after 45ns;
-- TB_clk <= '1' after 50ns;
-- TB_weight <= "000000000000" after 50ns;
-- TB_clk <= '0' after 55ns;
-- TB_clk <= '1' after 60ns;
-- TB_weight <= "000111110100" after 60ns;
-- TB_clk <= '0' after 65ns;
-- TB_reset <= '1' after 70ns;
-- TB_clk <= '1' after 75ns;
-- TB_weight <= "000000000001" after 75ns;
end tb;
I appreciate anybody that even read through these blocks of code. Thanks.

Related

vhdl invalid memory access (dangling accesses or stack size too small)

I'm trying to recreate a traffic light. And as it seems I have some kind of loop in my program since this message comes up whenever I run my testbench. I know for a fact that the loop in the testbench was okay, at least not the main problem, since once I commented it out, the error message came up again. Once I commented out the ampel (traffic light), the error wasn't there anymore. So my guess is that something is wrong with my ampel entity, but I can't find what it is.
Here the code:
library ieee;
use ieee.std_logic_1164.all;
entity ampel is
port (
clk, reset : in std_logic;
rot, gelb, gruen : out std_logic_vector(3 downto 0)
);
end ampel;
architecture rtl of ampel is
type t_zustand is (a,b,c,d,e,f,g,h);
signal zustand : t_zustand;
signal timer : integer;
begin
rot <= "1111";
process is
begin
wait on clk until clk = '1';
timer <= timer + 1;
if reset = '0' then
zustand <= a;
rot <= "1111";
gelb <= "0000";
gruen <= "0000";
timer <= 2;
else
case zustand is
when a =>
rot <= "1111";
gelb <= "0000";
gruen <= "0000";
if timer = 5 then
zustand <= b;
end if;
when b =>
rot <= "0101";
gelb <= "1010";
gruen <= "0000";
if timer = 10 then
zustand <= c;
end if;
when c =>
rot <= "0101";
gelb <= "0000";
gruen <= "1010";
if timer = 40 then
zustand <= d;
end if;
when d =>
rot <= "0101";
gelb <= "1010";
gruen <= "0000";
if timer = 45 then
zustand <= e;
end if;
when e =>
rot <= "1111";
gelb <= "0000";
gruen <= "0000";
if timer = 50 then
zustand <= b;
end if;
when f =>
rot <= "1010";
gelb <= "0101";
gruen <= "0000";
if timer = 55 then
zustand <= b;
end if;
when g =>
rot <= "1010";
gelb <= "0000";
gruen <= "0101";
if timer = 85 then
zustand <= b;
end if;
when h =>
rot <= "1010";
gelb <= "0101";
gruen <= "0000";
if timer = 90 then
zustand <= b;
end if;
end case;
end if;
end process;
end rtl ;
The testbench:
library ieee;
use ieee.std_logic_1164.all;
entity ampel_tb is
end ampel_tb;
architecture testbench of ampel_tb is
component ampel is
port(
clk, reset : in std_logic;
rot, gelb, gruen : out std_logic_vector(3 downto 0)
);
end component;
signal clk, reset : std_logic;
signal rot, gelb, gruen : std_logic_vector(3 downto 0);
begin
ampel0: ampel port map(clk => clk, reset => reset, rot => rot, gelb => gelb, gruen => gruen);
process begin
reset <= '0';
clk <= '0';
wait for 500 ms;
clk <= '1';
wait for 500 ms;
reset <= '1';
clk <= '0';
wait for 500 ms;
for I in 0 to 180 loop
clk <= '1';
wait for 500 ms;
clk <= '0';
wait for 500 ms;
end loop;
assert false report "End of test";
wait;
end process;
end testbench;

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

How can I add two std_logic_vectors that have been concatenated in VHDL?

I'm working on an ALU using a certain set of functions. I figured that the addition and bitshift portions would be a lot easier if I used an extra bit to store the carry out. I'm trying to concatenate an extra bit to two 8 bit long 'std_logic_vector's. The extra bit would hold the carry out in the addition.
However when I go to run the simulation after some debugging it doesn't look like the lines I used to give s_a and s_b their values are doing anything. If I were to take out the default values they come out empty.
I'm sure the error is something silly, I'm not to familiar with how concatenation works in vhdl, maybe theres a better way of storing the carry out, any help would be appreciated.
CODE:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity ALU is
Port (
A : in std_logic_vector(7 downto 0);
B : in std_logic_vector(7 downto 0);
SEL : in std_logic_vector(3 downto 0);
Cin : in std_logic;
Result : out std_logic_vector(7 downto 0);
C : out std_logic;
Z : out std_logic);
end ALU;
architecture Behavioral of ALU is
signal s_result: unsigned(8 downto 0) := "000000000";
signal s_cin: unsigned(8 downto 0) := "000000000";
signal s_a: unsigned(8 downto 0) := "000000000";
signal s_b: unsigned(8 downto 0) := "000000000";
signal s_exempt: std_logic := '0';
begin
s1: process(A, B, SEL, CIN)
begin
s_a <= ('0' & unsigned(A));
s_b <= ('0' & unsigned(B));
s_cin(0) <= Cin;
s_exempt <= '0';
case SEL is
when "0000" =>
s_result <= s_a + s_b;
C <= s_result(8);
when "0001" => --ADDc Add with carry
s_result <= s_a + s_b + s_cin;
C <= s_result(8);
when "0010" => --SUB
if(s_a > s_b) then
s_result <= s_a - s_b;
C <= '0';
else
s_result <= s_b - s_a;
C <= '1';
end if;
when "0011" => --SUBc Subtract with carry
if(s_a > (s_b + s_cin)) then
s_result <= s_a - s_b - s_cin;
C <= '0';
else
s_result <= s_b - s_a - s_cin;
C <= '1';
end if;
when "0100" => --CMP Compare both values
if(s_a > s_b) then
C <= '0';
Z <= '0';
elsif(s_a = s_b) then
Z <= '1';
C <= '0';
else
C <= '1';
Z <= '1';
end if;
s_exempt <= '1';
when "0101" => --AND
s_result <= s_a AND s_b;
C <= '0';
when "0110" => Z<= '1'; --OR
s_result <= s_a OR s_b;
C <= '0';
when "0111" => --EXOR
s_result <= s_a XOR s_b;
C <= '0';
when "1000" => --TEST, comparator, flag change ONLY
if((s_a AND s_b) = "000000000")
then
C <= '0';
Z <= '1';
else
C <= '0';
Z <= '0';
end if;
when "1001" => --LSL Left shift
s_result <= s_a sll 1;
C <= s_result(8);
when "1010" => --LSR RIght shift
C <= s_a(0);
s_result <= s_a srl 1;
when "1011" => Z<= '1'; --ROL Rotate Left
s_result <= s_a sll 1;
C <= s_result(8);
s_result(0) <= s_result(8);
when "1100" => Z<= '1'; --ROR Rotate Right
C <= s_a(0);
s_result <= s_a srl 1;
s_result(0) <= s_a(0);
when "1101" => --ASR Arithemetic Roation
C <= s_a(0);
s_result <= s_a srl 1;
s_result(8) <= s_a(7);
when "1110" => --MOV Moves data into result
s_result <= s_b;
s_exempt <= '1';
when others =>
s_result <= "000000000";
s_exempt <= '1';
Z <= '0';
C <= '0';
end case;
if(s_exempt = '0') -- Checks Result for 0 if hasn't been found
then
if(s_result(7 downto 0) = "00000000")
then
Z <= '1';
else Z <= '0';
end if;
end if;
Result <= std_logic_vector(s_result(7 downto 0));
end process;
end Behavioral;
TESTBENCH:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity simulation is
end simulation;
architecture Behavioral of simulation is
COMPONENT ALU
Port (
A : in std_logic_vector(7 downto 0);
B : in std_logic_vector(7 downto 0);
SEL : in std_logic_vector(3 downto 0);
Cin : in std_logic;
Result : out std_logic_vector(7 downto 0);
C : out std_logic;
Z : out std_logic
);
END COMPONENT;
signal A : std_logic_vector(7 downto 0) := "00000000";
signal B : std_logic_vector(7 downto 0) := "00000000";
signal SEL : std_logic_vector(3 downto 0) := "0000";
signal Cin : std_logic;
signal Result : std_logic_vector(7 downto 0) := "00000000";
signal C: std_logic := '0';
signal Z: std_logic := '0';
begin
uut: ALU PORT MAP (
A => A,
B => B,
SEL => SEL,
Cin => Cin,
Result => Result,
C => C,
Z => Z
);
stim_proc: process
begin
A <= "00000001";
B <= "00100001";
SEL <= "0000";
Cin <= '1';
wait for 10ns;
wait;
end process;
end Behavioral;
Any signal assigned in a process in VHDL is not updated until the process suspends. So, for example, the value of s_result from this line:
s_result <= s_a + s_b + s_cin;
will not be updated by the time that this line is executed:
C <= s_result(8);
You need to find out about delta delays, then once you have, you will need to rewrite your code.
VHDL is a hardware description language. You are designing hardware, not writing software. For example, your initialisation of all your signals will not be implemented in hardware, meaning that your simulation may well behave differently to your hardware:
signal s_result: unsigned(8 downto 0) := "000000000";
signal s_cin: unsigned(8 downto 0) := "000000000";
signal s_a: unsigned(8 downto 0) := "000000000";
signal s_b: unsigned(8 downto 0) := "000000000";
signal s_exempt: std_logic := '0';

divisor for std_logic_vector VHDL

I try to implement a divisor for std_logic_vector with the language VHDL.
After I have implemented it, I have to use GHDL but encountered this error :
vhdl:error: bound check failure at divisor.vhdl
It's correspond to this :
else ....
nb_reg <= (2*nb);
My code is :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port (
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end div;
architecture rtl of div is
-- Build a 2-D array type for the RAM
subtype word_t is unsigned((DATA_WIDTH-1) downto 0);
type memory_t is array(natural range <>) of word_t;
-- Declare the RAM signal.
signal ram, div : memory_t((2**ADDR_WIDTH)-1 downto 0);
-- Declare the n and max_reg signal.
signal n,m : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal max_reg : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb : unsigned(((2*DATA_WIDTH)-1) downto 0);
signal nb_reg : unsigned(((4*DATA_WIDTH)-3) downto 0);
-- Build div_reg, ram_reg
type memory_reg is array(natural range <>) of unsigned(((2*DATA_WIDTH)-1) downto 0);
signal ram_reg: memory_reg((2**ADDR_WIDTH)-1 downto 0);
begin
process(clk,reset)
begin
if (reset = '1') then
ram(waddr) <= X"00";
div(waddr) <= X"00";
max_reg <= X"0000";
ram_reg(waddr) <= X"0000";
n <= X"0000";
nb <= X"0000";
--nb_reg(((4*DATA_WIDTH)-3) downto 0) <= "0";
m <= X"0000";
elsif(rising_edge(clk)) then
ram(waddr) <= unsigned(data);
max_reg((DATA_WIDTH -1) downto 0) <= unsigned(max);
ram_reg(waddr)((DATA_WIDTH-1) downto 0) <= ram(waddr)((DATA_WIDTH-1) downto 0);
nb <= (nb+1);
if (ram(waddr) = max_reg)then
div(waddr) <= div(waddr)+1;
elsif (ram(waddr) > max_reg)then
while ((div(waddr)*(ram(waddr)) > max_reg) or (m <(DATA_WIDTH -1))) loop
div(waddr) <= (div(waddr))+1;
max_reg <= (max_reg) - (ram_reg(waddr));
m <= m+1;
end loop;
m <= (m-1);
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (nb*2);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
else
while (((div(waddr)*ram_reg(waddr)) < max_reg-1) or (n <(DATA_WIDTH)-(m))) loop
ram_reg(waddr)(((2*DATA_WIDTH)-1) downto 1) <= ram_reg(waddr)(((2*DATA_WIDTH)-2) downto 0);
ram_reg(waddr)(0) <= '0';
n <= n+1;
nb_reg <= (2*nb);
nb(((2*DATA_WIDTH)-1) downto 0) <= nb_reg(((2*DATA_WIDTH)-1) downto 0);
end loop;
ram_reg(waddr) <= ram_reg(waddr) - (max_reg);
div(waddr) <= (div(waddr))+(1/(nb));
end if;
else null;
end if;
end process;
q <= std_logic_vector(div(waddr));
end rtl;
The test bench :
-- descrizione del Test_bench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity div_tb is
end div_tb;
architecture behaviour of div_tb is
--dichiarazione dei COMPONENT ovvero la Unit Under Test
component div is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 3
);
port
(
clk : in std_logic;
reset : in std_logic;
raddr : in natural range 0 to 2**ADDR_WIDTH - 1;
waddr : in natural range 0 to 2**ADDR_WIDTH - 1;
max : in std_logic_vector((DATA_WIDTH -1) downto 0);
data : in std_logic_vector((DATA_WIDTH -1) downto 0);
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end component;
-- Clock period definitions
constant clk_period : time := 1 us;
constant DATA_WIDTH : natural := 8;
constant ADDR_WIDTH : natural := 3;
signal CLK_tb: std_logic := '0';
signal RESET_tb: std_logic := '1';
signal raddr_tb, waddr_tb : natural range 0 to 2**ADDR_WIDTH - 1;
signal data_tb, q_tb, max_tb : std_logic_vector((DATA_WIDTH -1) downto 0);
signal I : integer := 0; -- variabile per il conteggio dei clock
begin
clk_process: process --processo di generazione del CLK
begin
CLK_tb <= '0';
wait for clk_period/2;
CLK_tb <= '1';
wait for clk_period/2;
I<=I+1;
if I=200 then wait; -- durata della simulazione: 30 colpi di CLK
else null;
end if;
end process;
-- istanziazione della Unit Under Test
UUT: div generic map (ADDR_WIDTH => 3, DATA_WIDTH => 8)
port map (clk=>clk_tb, reset=>RESET_tb, raddr => raddr_tb, waddr => waddr_tb , data => data_tb, q => q_tb, max => max_tb);
stimoli: process
begin
RESET_tb <= '1';
wait for clk_period*3;
RESET_tb <= '0';
wait;
end process;
we: process
begin
max_tb <= "11100110";
wait;
end process;
Data : process
begin
data_tb <= "00000000"; raddr_tb <= 0; waddr_tb <= 0; wait for clk_period*3;
data_tb <= "01010110"; raddr_tb <= 1; waddr_tb <= 1; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 2; waddr_tb <= 2; wait for clk_period*8;
data_tb <= "11001110"; raddr_tb <= 3; waddr_tb <= 3; wait for clk_period*8;
data_tb <= "01000111"; raddr_tb <= 4; waddr_tb <= 4; wait for clk_period*8;
data_tb <= "11100110"; raddr_tb <= 5; waddr_tb <= 5; wait for clk_period*8;
data_tb <= "01000110"; raddr_tb <= 6; waddr_tb <= 6; wait for clk_period*8;
data_tb <= "01010110"; raddr_tb <= 7; waddr_tb <= 7; wait for clk_period*8;
wait;
end process;
end behaviour;
I use the 2007 version of GHDL and it is not possible for me to update, my teacher wants me to use this one.
Could somebody help me with this code?
The multiplication operator in the numeric_std package is defined thus for multiplying a natural by an unsigned:
-- Id: A.18
function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
-- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0)
-- Result: Multiplies an UNSIGNED vector, R, with a nonnegative
-- INTEGER, L. L is converted to an UNSIGNED vector of
-- SIZE R'LENGTH before multiplication.
As you can see, the output is twice the width of the unsigned argument minus 1. In this line
nb <= std_logic_vector(2*unsigned(nb));
you are assigning the result back to the unsigned operand, which obviously is not a different width to itself.
So, you either need an intermediate variable of the right width or perhaps a shift left?

Resources