VHDL - comparing signals (integers) in IF-statement - if-statement

I am trying to write code to change the frequency of my clock. But the output is always zeroes...
signal cycle_counter : integer := 0;
signal HALFCYCLES : integer;
signal MY_CLK1, temporal : std_logic :='0';
frequency_divider: process (Clk,cycle_counter, HALFCYCLES)
begin
if rising_edge(Clk) then
cycle_counter <= cycle_counter + 1;
if cycle_counter = (HALFCYCLES-1) then
temporal <= NOT(temporal);
cycle_counter <= 0;
end if;
end if;
MY_CLK1 <= temporal;
end process frequency_divider;
When i put instead of HALFCYCLES-1 some integer value, all is working just fine, but i need this signal to be changeable.
I believe, that the problem is in comparing, but can't detect it.
I tried to make HALFCYCLES a variable, instead of signal, but compiler was against it :)
Full code (main goan - to put in the LED two different animations. Frequency and type of animation you should choose via switchers (input logic_vector S)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LED2 is
generic (FIFT : std_logic_vector (15 downto 0) := "1111111111111111";
ZERO : std_logic_vector (15 downto 0) := "0000000000000000");
Port ( S : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
R : in STD_LOGIC;
LED : out STD_LOGIC_VECTOR (7 downto 0));
end LED2;
architecture Behavioral of LED2 is
signal statement: std_logic_vector (7 downto 0);
signal cycle_counter : integer := 0;
signal CNT1, CNT2, CURCNT, CNT_NO : integer:= 0;
signal HALFCYCLES : integer;
signal MY_CLK1, MY_CLK2, temporal : std_logic :='0';
begin
frequency_divider: process (Clk,cycle_counter, HALFCYCLES) begin
if rising_edge(Clk) then
cycle_counter <= cycle_counter + 1;
if cycle_counter = (HALFCYCLES-1) then --(HALFCYCLES-1)
temporal <= NOT(temporal);
cycle_counter <= 0;
end if;
end if;
MY_CLK1 <= temporal;
MY_CLK2 <= temporal;
end process frequency_divider;
counter1: PROCESS (MY_CLK1, R)
BEGIN
IF (MY_CLK1 = '1' AND MY_CLK1'EVENT) THEN
IF (R='1') THEN
CNT1 <=0;
ELSIF (CNT1 = 15) THEN
CNT1 <= 0;
ELSE
CNT1 <= CNT1 + 1;
END IF;
END IF;
END PROCESS counter1;
counter2: PROCESS (MY_CLK2, R)
BEGIN
IF (MY_CLK2 = '1' AND MY_CLK2'EVENT) THEN
IF (R='1') THEN
CNT2 <=0;
ELSE
if (CNT2 = 15) then
CNT2 <= 0;
else
CNT2 <= CNT2 + 1;
end if;
END IF;
END IF;
END PROCESS counter2;
freq_changer: PROCESS (CNT1, CNT2, S)
BEGIN
IF (S(7) = '1')
THEN HALFCYCLES <= 50000000; CURCNT <= CNT1; CNT_NO <= 1;--1hz
ELSIF (S(6) = '1')
THEN HALFCYCLES <= 5000000; CURCNT <= CNT2; CNT_NO <= 2;--10hz
ELSIF (S(5) = '1')
THEN HALFCYCLES <= 500000; CURCNT <= CNT1; CNT_NO <= 1;--100hz
ELSIF (S(4) = '1')
THEN HALFCYCLES <= 50000; CURCNT <= CNT2; CNT_NO <= 2;--1khz
ELSIF (S(3) = '1')
THEN HALFCYCLES <= 5000; CURCNT <= CNT1; CNT_NO <= 1;--10khz
ELSIF (S(2) = '1')
THEN HALFCYCLES <= 500; CURCNT <= CNT2; CNT_NO <= 2;--100khz
ELSIF (S(1) = '1')
THEN HALFCYCLES <= 50; CURCNT <= CNT1; CNT_NO <= 1;--1mhz
ELSIF (S(0) = '1')
THEN HALFCYCLES <= 10; CURCNT <= CNT2; CNT_NO <= 2;--5mhz
ELSE HALFCYCLES <= 5; CURCNT <= CNT1; CNT_NO <= 1;--10mhz
END IF;
END PROCESS freq_changer;
main: PROCESS (CNT_NO, CURCNT)
BEGIN
c: CASE CNT_NO IS
WHEN 2 =>
counter2:CASE CURCNT IS
WHEN 0 => statement <= "00000001";
WHEN 1 => statement <= "00000010";
WHEN 2 => statement <= "00000100";
WHEN 3 => statement <= "00001000";
WHEN 4 => statement <= "00010000";
WHEN 5 => statement <= "00100000";
WHEN 6 => statement <= "01000000";
WHEN 7 => statement <= "10000000";
WHEN 8 => statement <= "10000000";
WHEN 9 => statement <= "01000000";
WHEN 10 => statement <= "00100000";
WHEN 11 => statement <= "00010000";
WHEN 12 => statement <= "00001000";
WHEN 13 => statement <= "00000100";
WHEN 14 => statement <= "00000010";
WHEN 15 => statement <= "00000001";
WHEN OTHERS => statement <= "00000000";
END CASE counter2;
WHEN OTHERS =>
counter1:CASE CURCNT IS
WHEN 0 => statement <= "10000001";
WHEN 1 => statement <= "01000010";
WHEN 2 => statement <= "00100100";
WHEN 3 => statement <= "00011000";
WHEN 4 => statement <= "00011000";
WHEN 5 => statement <= "00100100";
WHEN 6 => statement <= "01000010";
WHEN 7 => statement <= "10000001";
WHEN 8 => statement <= "00011000";
WHEN 9 => statement <= "00100100";
WHEN 10 => statement <= "01000010";
WHEN 11 => statement <= "10000001";
WHEN 12 => statement <= "10000001";
WHEN 13 => statement <= "01000010";
WHEN 14 => statement <= "00100100";
WHEN 15 => statement <= "00011000";
WHEN OTHERS => statement <= "00000000";
END CASE counter1;
END CASE c;
LED <= statement;
END PROCESS main;
end Behavioral;
testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.Numeric_Std.all;
ENTITY LED_controller_tb IS
END LED_controller_tb;
ARCHITECTURE behavior OF LED_controller_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT LED2
PORT(
S : IN std_logic_vector(7 downto 0);
Clk : IN std_logic;
R : IN std_logic;
LED : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
--Inputs
signal S : std_logic_vector(7 downto 0) := (others => '0');
signal Clk : std_logic := '0';
signal R : std_logic := '0';
--Outputs
signal LED : std_logic_vector(7 downto 0);
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: LED2 PORT MAP (
S => S,
Clk => Clk,
R => R,
LED => LED
);
-- 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.
wait for Clk_period * 8;
S <= std_logic_vector(to_unsigned(to_integer(unsigned(S)) + 1, 8));
-- insert stimulus here
end process;
reset: PROCESS
BEGIN
WAIT FOR 1 us;
R <= '1';
WAIT FOR 500 ns;
R <= '0';
END PROCESS reset;
END;

I think you are changing S far too quickly in your testbench. I changed line in your testbench to wait for a much longer time and it seems to work OK.
As recommended by Andy, I would change line 26 of your design to
if cycle_counter >= (HALFCYCLES-1) then --(HALFCYCLES-1)
Here's the (modified) testbench in full. I have also added a process to stop the simulation; otherwise, it runs forever:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.Numeric_Std.all;
ENTITY LED_controller_tb IS
END LED_controller_tb;
ARCHITECTURE behavior OF LED_controller_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT LED2
PORT(
S : IN std_logic_vector(7 downto 0);
Clk : IN std_logic;
R : IN std_logic;
LED : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
--Inputs
signal S : std_logic_vector(7 downto 0) := (others => '0');
signal Clk : std_logic := '0';
signal R : std_logic := '0';
--Outputs
signal LED : std_logic_vector(7 downto 0);
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: LED2 PORT MAP (
S => S,
Clk => Clk,
R => R,
LED => LED
);
-- 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.
wait for Clk_period * 800; -- WAIT MUCH LONGER BEFORE CHANGING S !
S <= std_logic_vector(to_unsigned(to_integer(unsigned(S)) + 1, 8));
-- insert stimulus here
end process;
reset: PROCESS
BEGIN
WAIT FOR 1 us;
R <= '1';
WAIT FOR 500 ns;
R <= '0';
END PROCESS reset;
STOP_SIM: process -- OTHERWISE THE SIM RUNS FOREVER
begin
wait for Clk_period * 4000;
assert FALSE severity FAILURE;
end process;
END;
http://www.edaplayground.com/x/7XS

Related

How to make lemmas about changes made to heap objects?

I'm trying to implement a MaxHeap using Dafny based on the code from Intro. to Algorithms, CLRS 3rd edition, section 6.1, page 153 or the Max-Heapify function here. I switched from using recursion to a while loop because that seemed a bit easier to handle in Dafny.
Trying to prove the heap property on an array after calling the heapify function. In particular I was hoping to be able to use the require statement on heapify to assert that triples which didn't change in the heap which were satisfying the heap property before an update, are satisfying the heap property after the update.
However, after making any changes to the array it seems like it forgets all about the require/invariant statement. Even if I show that the value are the same before and after the update it still no longer passes the assertion. I pulled out the update into the swap method.
I was hoping I could write a lemma asserting this fact but it seems like lemmas don't allow modifying the heap or using old() or calling a method. Is there a way to write a lemma for this?
function method parent(i: int): int
{
i/2
}
function method left(i: int): int
{
2*i
}
function method right(i: int): int
{
2*i+1
}
class MaxHeap {
var data: array<int>
ghost var repr: set<object>
constructor(data: array<int>)
ensures this.data == data
ensures this in repr
{
this.data := data;
this.repr := {this};
}
predicate method MaxHeapChildren(i: int)
reads this, this.data
requires 1 <= i
{
(left(i) > this.data.Length || this.data[i-1] >= this.data[left(i)-1]) && (right(i) > this.data.Length || this.data[i-1] >= this.data[right(i)-1])
}
method heapify(i: int) returns (largest: int)
modifies this.data
requires 1 <= i <= this.data.Length
requires forall x :: i < x <= this.data.Length ==> MaxHeapChildren(x)
// ensures multiset(this.data[..]) == multiset(old(this.data[..]))
ensures forall x :: i <= x <= this.data.Length ==> MaxHeapChildren(x)
decreases this.data.Length - i
{
var i' := i;
ghost var oldi := i;
largest := i;
var l := left(i);
var r := right(i);
ghost var count := 0;
ghost var count' := 1;
while !MaxHeapChildren(i')
invariant count' == count + 1;
invariant 1 <= largest <= this.data.Length
invariant l == left(i')
invariant r == right(i')
invariant 1 <= i' <= this.data.Length
invariant i' == i || i' == left(oldi) || i' == right(oldi)
invariant largest == i'
invariant count == 0 ==> oldi == i
invariant oldi > 0
invariant count > 0 ==> oldi == parent(i')
invariant count > 0 ==> MaxHeapChildren(oldi)
invariant count > 0 ==> forall x :: i <= x < i' ==> old(this.data)[x] == this.data[x]
invariant count > 0 ==> forall x :: i <= x < i' && left(x+1) < this.data.Length ==> old(this.data)[left(x+1)] == this.data[left(x+1)]
invariant count > 0 ==> forall x :: i <= x < i' && right(x+1) < this.data.Length ==> old(this.data)[right(x+1)] == this.data[right(x+1)]
// invariant count > 0 ==> forall x :: i <= x <= i' && left(x+1) ==> MaxHeapChildren(left(x+1))
invariant forall x :: i <= x <= this.data.Length && x != i' ==> MaxHeapChildren(x)
decreases this.data.Length-i';
{
if l <= this.data.Length && this.data[l-1] > this.data[i'-1] {
largest := l;
}
if r <= this.data.Length && this.data[r-1] > this.data[largest-1] {
largest := r;
}
if largest != i' {
assert forall x :: i < x <= this.data.Length && x != i' ==> MaxHeapChildren(x);
swap(this, i', largest);
label AfterChange:
oldi := i';
assert MaxHeapChildren(oldi);
i' := largest;
assert forall x :: largest < x <= this.data.Length && x != i' ==> MaxHeapChildren(x);
l := left(i');
r := right(i');
assert forall x :: i <= x < i' ==> old#AfterChange(this.data[x]) == this.data[x] && left(x+1) < this.data.Length ==> old(this.data)[left(x+1)] == this.data[left(x+1)] && right(x+1) < this.data.Length ==> old(this.data)[right(x+1)] == this.data[right(x+1)];
}else{
assert MaxHeapChildren(i');
assert MaxHeapChildren(oldi);
}
count := count + 1;
count' := count' + 1;
}
}
}
method swap(heap: MaxHeap, i: int, largest: int)
modifies heap.data
requires 1 <= i < largest <= heap.data.Length
requires heap.data[largest-1] > heap.data[i-1]
requires left(i) <= heap.data.Length ==> heap.data[largest-1] >= heap.data[left(i)-1]
requires right(i) <= heap.data.Length ==> heap.data[largest-1] >= heap.data[right(i)-1]
requires forall x :: i <= x <= heap.data.Length && x != i ==> heap.MaxHeapChildren(x)
ensures heap.data[i-1] == old(heap.data[largest-1])
ensures heap.data[largest-1] == old(heap.data[i-1])
ensures heap.MaxHeapChildren(i)
ensures forall x :: 1 <= x <= heap.data.Length && x != i && x != largest ==> heap.data[x-1] == old(heap.data[x-1])
ensures forall x :: i <= x <= heap.data.Length && x != largest ==> heap.MaxHeapChildren(x)
{
ghost var oldData := heap.data[..];
var temp := heap.data[i-1];
heap.data[i-1] := heap.data[largest-1];
heap.data[largest-1] := temp;
var z:int :| assume i < z <= heap.data.Length && z != largest;
var lz: int := left(z);
var rz: int := right(z);
assert heap.data[z-1] == old(heap.data[z-1]);
assert lz != i && lz != largest && lz <= heap.data.Length ==> heap.data[lz-1] == old(heap.data[lz-1]);
assert rz != i && rz != largest && rz <= heap.data.Length ==> heap.data[rz-1] == old(heap.data[rz-1]);
assert heap.MaxHeapChildren(z);
}
/**
heapify(4)
length = 17
i = 4
left = 8, 7 (0based)
right = 9, 8 (0based)
x in 5 .. 17 :: MaxHeapChildren(x) (i+1)..17
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,3,14,12,10, 8, 6, 4, 2, 0, 1,-2, 4, 4,-5]
i = 8
left = 16
right = 17
x in i' .. i-1 :: MaxHeapChildren (4..15)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,8,14,12,10, 3, 6, 4, 2, 0, 1,-2, 4, 4,-5]
i = 16
left = 32
right = 33
x in i' .. i-1 :: MaxHeapChildren (4..16) + 17.. MaxHeapChildren
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,8,14,12,10, 4, 6, 4, 2, 0, 1,-2, 4, 3,-5]
*/
Yes, I think what you are looking for is called a twostate lemma
Basically, you can use old() in their specification, and at the call site, you can specify which heap to consider for calls to old() by suffixing the lemma's name by #a, if label a: existed before that method's call.

How to simplify sequential logic design by eliminating nested if-else statements

I have a design I've implemented using vhdl that is triggered based on a clock that sends an input signal to one of 8 output channels based on the sel input and also another 2 bit input. The elaborated design shows a lot of nesting due to the many if-else statements. So, I'm curious as to if there's a way to alleviate the nesting using case statements or some other method. I'm unfamiliar with doing this using case statements because I have two inputs that determine the output channel. The code that I currently have is displayed below.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--Inputs and outputs to entity
entity DSA_Worker is
Port ( DB_Select : in STD_LOGIC;
Atten : in STD_LOGIC_VECTOR ( 7 downto 0);
enable : in STD_LOGIC;
clk: in STD_LOGIC;
reset: in STD_LOGIC;
chip_select : in STD_LOGIC_VECTOR (1 downto 0);
DBA_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0));
end DSA_Worker;
architecture Behavioral of DSA_Worker is
begin
process(clk)
begin
if rising_edge(clk) then
--if reset is high, all outputs go to 0
if reset = '1'then
DBA_TX1_DSA <= (others =>'0');
DBA_TX2_DSA <= (others =>'0');
DBA_RX1_DSA <= (others =>'0');
DBA_RX2_DSA <= (others =>'0');
DBB_TX1_DSA <= (others =>'0');
DBB_TX2_DSA <= (others =>'0');
DBB_RX1_DSA <= (others =>'0');
DBB_RX2_DSA <= (others =>'0');
-- attenuation values sent to channels based on DB_select value(0/1) and chip select value
--DB_select - 0 is for DB-A and 1 for DB- B and chip_select determines the channel
elsif enable = '1'then
if(DB_Select='0' and chip_select = "00") then -- attenuation value sent to first channel
DBA_TX1_DSA(0) <= Atten(0);
DBA_TX1_DSA(1) <= Atten(1);
DBA_TX1_DSA(2) <= Atten(2);
DBA_TX1_DSA(3) <= Atten(3);
DBA_TX1_DSA(4) <= Atten(4);
DBA_TX1_DSA(5) <= Atten(5);
elsif (DB_Select='0' and chip_select = "01") then
DBA_TX2_DSA(0) <= Atten(0);
DBA_TX2_DSA(1) <= Atten(1);
DBA_TX2_DSA(2) <= Atten(2);
DBA_TX2_DSA(3) <= Atten(3);
DBA_TX2_DSA(4) <= Atten(4);
DBA_TX2_DSA(5) <= Atten(5);
elsif (DB_Select='0' and chip_select = "10") then
DBA_RX1_DSA(0) <= Atten(0);
DBA_RX1_DSA(1) <= Atten(1);
DBA_RX1_DSA(2) <= Atten(2);
DBA_RX1_DSA(3) <= Atten(3);
DBA_RX1_DSA(4) <= Atten(4);
DBA_RX1_DSA(5) <= Atten(5);
elsif (DB_Select='0' and chip_select = "11") then
DBA_RX2_DSA(0) <= Atten(0);
DBA_RX2_DSA(1) <= Atten(1);
DBA_RX2_DSA(2) <= Atten(2);
DBA_RX2_DSA(3) <= Atten(3);
DBA_RX2_DSA(4) <= Atten(4);
DBA_RX2_DSA(5) <= Atten(5);
-- Attenuation values being set for DB-B
elsif (DB_Select='1' and chip_select = "00") then
DBB_TX1_DSA(0) <= Atten(0);
DBB_TX1_DSA(1) <= Atten(1);
DBB_TX1_DSA(2) <= Atten(2);
DBB_TX1_DSA(3) <= Atten(3);
DBB_TX1_DSA(4) <= Atten(4);
DBB_TX1_DSA(5) <= Atten(5);
elsif (DB_Select='1' and chip_select = "01") then
DBB_TX2_DSA(0) <= Atten(0);
DBB_TX2_DSA(1) <= Atten(1);
DBB_TX2_DSA(2) <= Atten(2);
DBB_TX2_DSA(3) <= Atten(3);
DBB_TX2_DSA(4) <= Atten(4);
DBB_TX2_DSA(5) <= Atten(5);
elsif (DB_Select='1' and chip_select = "10") then
DBB_RX1_DSA(0) <= Atten(0);
DBB_RX1_DSA(1) <= Atten(1);
DBB_RX1_DSA(2) <= Atten(2);
DBB_RX1_DSA(3) <= Atten(3);
DBB_RX1_DSA(4) <= Atten(4);
DBB_RX1_DSA(5) <= Atten(5);
else
DBB_RX2_DSA(0) <= Atten(0);
DBB_RX2_DSA(1) <= Atten(1);
DBB_RX2_DSA(2) <= Atten(2);
DBB_RX2_DSA(3) <= Atten(3);
DBB_RX2_DSA(4) <= Atten(4);
DBB_RX2_DSA(5) <= Atten(5);
end if;
end if;
end if;
end process;
end Behavioral;
I did try to produce a simplified design using case statements as illustrated below
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity dsa_case is
Port (
DB_Select : in STD_LOGIC;
Atten : in STD_LOGIC_VECTOR ( 7 downto 0);
enable : in STD_LOGIC;
clk: in STD_LOGIC;
reset: in STD_LOGIC;
chip_select : in STD_LOGIC_VECTOR (1 downto 0);
DBA_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBA_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
DBB_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0));
end dsa_case;
architecture Behavioral of dsa_case is
begin
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
DBA_TX1_DSA <= (others =>'0');
DBA_TX2_DSA <= (others =>'0');
DBA_RX1_DSA <= (others =>'0');
DBA_RX2_DSA <= (others =>'0');
DBB_TX1_DSA <= (others =>'0');
DBB_TX2_DSA <= (others =>'0');
DBB_RX1_DSA <= (others =>'0');
DBB_RX2_DSA <= (others =>'0');
elsif enable = '1'then
-- DB_Select <='0';
case chip_select is
when "00"=> -- attenuation value sent to first channel
DBA_TX1_DSA(0) <= Atten(0);
DBA_TX1_DSA(1) <= Atten(1);
DBA_TX1_DSA(2) <= Atten(2);
DBA_TX1_DSA(3) <= Atten(3);
DBA_TX1_DSA(4) <= Atten(4);
DBA_TX1_DSA(5) <= Atten(5);
when "01"=>
DBA_TX2_DSA(0) <= Atten(0);
DBA_TX2_DSA(1) <= Atten(1);
DBA_TX2_DSA(2) <= Atten(2);
DBA_TX2_DSA(3) <= Atten(3);
DBA_TX2_DSA(4) <= Atten(4);
DBA_TX2_DSA(5) <= Atten(5);
when "10"=>
DBA_RX1_DSA(0) <= Atten(0);
DBA_RX1_DSA(1) <= Atten(1);
DBA_RX1_DSA(2) <= Atten(2);
DBA_RX1_DSA(3) <= Atten(3);
DBA_RX1_DSA(4) <= Atten(4);
DBA_RX1_DSA(5) <= Atten(5);
when "11"=>
DBA_RX2_DSA(0) <= Atten(0);
DBA_RX2_DSA(1) <= Atten(1);
DBA_RX2_DSA(2) <= Atten(2);
DBA_RX2_DSA(3) <= Atten(3);
DBA_RX2_DSA(4) <= Atten(4);
DBA_RX2_DSA(5) <= Atten(5);
-- Attenuation values being set for DB-B
-- DB_Select <= '1';
when "00"=>
DBB_TX1_DSA(0) <= Atten(0);
DBB_TX1_DSA(1) <= Atten(1);
DBB_TX1_DSA(2) <= Atten(2);
DBB_TX1_DSA(3) <= Atten(3);
DBB_TX1_DSA(4) <= Atten(4);
DBB_TX1_DSA(5) <= Atten(5);
-- DB_Select <= '1';
when "01" =>
DBB_TX2_DSA(0) <= Atten(0);
DBB_TX2_DSA(1) <= Atten(1);
DBB_TX2_DSA(2) <= Atten(2);
DBB_TX2_DSA(3) <= Atten(3);
DBB_TX2_DSA(4) <= Atten(4);
DBB_TX2_DSA(5) <= Atten(5);
-- DB_Select <= '1';
when "10"=>
DBB_RX1_DSA(0) <= Atten(0);
DBB_RX1_DSA(1) <= Atten(1);
DBB_RX1_DSA(2) <= Atten(2);
DBB_RX1_DSA(3) <= Atten(3);
DBB_RX1_DSA(4) <= Atten(4);
DBB_RX1_DSA(5) <= Atten(5);
when others=>
DBB_RX2_DSA(0) <= Atten(0);
DBB_RX2_DSA(1) <= Atten(1);
DBB_RX2_DSA(2) <= Atten(2);
DBB_RX2_DSA(3) <= Atten(3);
DBB_RX2_DSA(4) <= Atten(4);
DBB_RX2_DSA(5) <= Atten(5);
end case;
end if;
end if;
end process;
end Behavioral;
However, it did fail to produce an elaborated design due to 5 errors, all like this
[Synth 8-517] overlapping choice 2'b00 in case statement ["/home/n310-osp/case_statement_design/case_statement_design.srcs/sources_1/new/dsa_case.vhd":108]
Personally I don't mind your if-else structure. I think you mostly have a readability issue, with a lot of redundancy (in this case the check on DB_Select inside each case) and inconsistent indentation.
This is how I'd improve the code inside the process:
process(clk)
begin
if rising_edge(clk) then
--if reset is high, all outputs go to 0
if reset = '1' then
DBA_TX1_DSA <= (others=>'0');
DBA_TX2_DSA <= (others=>'0');
DBA_RX1_DSA <= (others=>'0');
DBA_RX2_DSA <= (others=>'0');
DBB_TX1_DSA <= (others=>'0');
DBB_TX2_DSA <= (others=>'0');
DBB_RX1_DSA <= (others=>'0');
DBB_RX2_DSA <= (others=>'0');
-- attenuation values sent to channels based on DB_select value(0/1) and chip select value
-- DB_select - 0 is for DB-A and 1 for DB- B and chip_select determines the channel
elsif enable = '1'then
if DB_Select = '0' then
if chip_select = "00" then -- attenuation value sent to first channel
DBA_TX1_DSA(5 downto 0) <= Atten(5 downto 0);
elsif chip_select = "01" then
DBA_TX2_DSA(5 downto 0) <= Atten(5 downto 0);
elsif chip_select = "10" then
DBA_RX1_DSA(5 downto 0) <= Atten(5 downto 0);
else
DBA_RX2_DSA(5 downto 0) <= Atten(5 downto 0);
end if;
else -- Attenuation values being set for DB-B
if chip_select = "00" then
DBB_TX1_DSA(5 downto 0) <= Atten(5 downto 0);
elsif chip_select = "01" then
DBB_TX2_DSA(5 downto 0) <= Atten(5 downto 0);
elsif chip_select = "10" then
DBB_RX1_DSA(5 downto 0) <= Atten(5 downto 0);
else
DBB_RX2_DSA(5 downto 0) <= Atten(5 downto 0);
end if;
end if;
end if;
end if;
end process;
end Behavioral;
You could replace the if-else structure with when-else, but that's just a matter of preference.

VHDL coding error “Else clause after check for clock not supported”

The function of the code is given an opcode, it will perform a task at the rising edge of the clock. I'm a second year undergrad student, so any help/input will be appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU is Port (
X,Y :IN BIT_VECTOR(2 downto 0);
OPcode :IN BIT_VECTOR(2 downto 0);
Z :OUT BIT_VECTOR(5 downto 0);
CLK :IN BIT;
TempValX:INOUT BIT_VECTOR(5 downto 0));
end ALU;
architecture Circuit of ALU is signal g: BIT_VECTOR(3 downto 0);
signal C: BIT_VECTOR(3 downto 0);
signal p, u, r : bit_vector(2 downto 0);
signal s: Bit_vector(5 downto 0);
Component ThreeBitFA is
PORT (X,Y :IN BIT_VECTOR(2 downto 0);
C :INOUT BIT_VECTOR(3 downto 0));
end component; begin adder:ThreeBitFA port map(
X => X,
Y => Y,
C => C);
Process(X,Y,CLK,OPcode)
begin
IF OPcode = "000" THEN ----------------ADD OPcode
IF (CLK'EVENT AND CLK = '1') THEN
tempvalx <= "00" & C;
Z <= tempvalx;
end if;
ELSIF OPcode = "001" THEN ----------------MULT OPcode
IF (CLK'EVENT AND CLK = '1') THEN
IF Y(0) = '1' THEN P <= X; ELSE P <= "000"; END IF;
IF Y(1) = '1' THEN u <= X; ELSE u <= "000"; END IF;
IF Y(2) = '1' THEN R <= X; ELSE R <= "000"; END IF;
z(0) <= P(0);
z(1) <= P(1) XOR u(0); s(0) <= P(1) AND u(0);
z(2) <= P(2) XOR u(1) XOR R(0) XOR s(0); s(1) <= s(0) AND P(2); s(2) <= u(1) AND R(0);
z(3) <= u(2) XOR R(1) XOR s(1) XOR s(2); s(3) <= s(2) AND s(1); s(4) <= u(2) AND R(1);
z(4) <= R(2) XOR s(3) XOR s(4); s(5) <= s(3) AND s(4);
z(5) <= s(5);
end if;
ELSIF (OPcode = "010") THEN ------------AND OPcode
IF (CLK'EVENT AND CLK = '1') THEN
Z <= "000" & (X AND Y);
end IF;
ELSIF (OPcode = "011") THEN ------------OR Opcode
IF (CLK'EVENT AND CLK = '1') THEN
Z <= "000" & (X OR Y);
end IF;
ELSIF (OPcode = "100") THEN ------------XOR Opcode
IF (CLK'EVENT AND CLK = '1') THEN
Z <= "000" & (X XOR Y);
end IF;
ELSIF (OPcode = "101") THEN ------------NOT Opcode
IF (CLK'EVENT AND CLK = '1') THEN
Z <= "000" & (NOT X);
end IF;
ELSIF (OPcode = "110") THEN -----------Rshift OPcode
IF (CLK'EVENT AND CLK = '1') THEN
TempValX <= "000" & X;
Z <= '0' & TempValX(5 downto 1);
ELSIF (OPcode = "111") THEN -----------Lshift OPcode
IF (CLK'EVENT AND CLK = '1') THEN
TempValX <= "000" & X;
Z <= TempValX(4 downto 0) & '0';
end IF;
ELSE
Null;
END IF;
END IF; END Process; end Circuit;
Couple of things stand out.
If you only need to "perform a task at the rising edge of the clock", you only need 'CLK' in your process sensitivity list.
The order of precedence in your if-else inside the process is wrong. All of the opcode decoding logic should be inside the check for rising edge clock.

VHDL - if < statement not working

I am trying to develop an autonomous car. I have a sensor that counts the number of laps of our car's wheels. When the number of laps reaches a specific input number it should change states, but the if statement doesn't seem to be working. Instead of comparing the two numbers, it enters the else statement until the input vueltas is all '1'. If I change the code, and write if (vueltas < 15) it works. But I need the number to be changeable. This is the code, I want the program to stay in the same state until the number of lapsis this imput number. I have already proved that the input number is correct and is 15. The elsif(obst = '1') is in case the car detects an obstacle, but it doesn't matter with this problem.
Note: vueltas = laps in spanish
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Circuito is Port (
clk : in STD_LOGIC;
ir1 : in STD_LOGIC;
ir2 : in STD_LOGIC;
moverCoche : in STD_LOGIC;
angulo : in STD_LOGIC_VECTOR(4 downto 0);
vMaxCurva : in STD_LOGIC_VECTOR(4 downto 0);
posInicial : in STD_LOGIC_VECTOR(9 downto 0);
vueltasCurva : in STD_LOGIC_VECTOR(9 downto 0);
vueltasRecta : in STD_LOGIC_VECTOR(9 downto 0);
obst : in STD_LOGIC;
servoOut : out STD_LOGIC;
motorOut : out STD_LOGIC;
vueltasLed : out STD_LOGIC_VECTOR(9 downto 0);
vueltasDentroDeCircuito : out STD_LOGIC_VECTOR(11 downto 0);
revolucionesPorSeg : out STD_LOGIC_VECTOR(11 downto 0));
end Circuito;
architecture Behavioral of Circuito is
component motor_pwm_clk32kHz is Port (
clk : in STD_LOGIC;
entrada : in STD_LOGIC_VECTOR(4 downto 0);
salida : out STD_LOGIC);
end component;
component servo_pwm_clk32kHz is Port (
clk : in STD_LOGIC;
pos : in STD_LOGIC_VECTOR(4 downto 0);
servo : out STD_LOGIC);
end component;
component Contador_Vueltas is Port (
out1 : in STD_LOGIC; --Negro: 1 Blanco: 0
out2 : in STD_LOGIC; --Negro: 1 Blanco: 0
vueltas : out STD_LOGIC_VECTOR (9 downto 0);
rst : in STD_LOGIC;
clk : in STD_LOGIC);
end component;
component revoluciones is Port (
clk : in STD_LOGIC;
vueltasDentroDeCircuito : in STD_LOGIC_VECTOR(11 downto 0);
revoluciones : out STD_LOGIC_VECTOR(11 downto 0));
end component;
signal posServo, posMotor: STD_LOGIC_VECTOR(4 downto 0);
signal vueltas : STD_LOGIC_VECTOR(9 downto 0);
signal primeraVuelta : STD_LOGIC := '1';
signal sigReiniciarVueltas : STD_LOGIC;
signal sigVueltasDentroDeCircuito : STD_LOGIC_VECTOR(11 downto 0);
signal sigVueltasInicioEstado : STD_LOGIC_VECTOR(11 downto 0);
--signal sigVueltasRecta : unsigned := to_integer(unsigned(vueltasRecta));
--constant sigVueltasRecta : STD_LOGIC_VECTOR(9 downto 0) := "0000011110";
--constant sigVueltasCurva : STD_LOGIC_VECTOR(9 downto 0) := "0000011110";
signal flag : STD_LOGIC := '0';
signal Qt: STD_LOGIC_VECTOR(3 downto 0);
SUBTYPE STATE_TYPE IS STD_LOGIC_VECTOR(3 downto 0);
SIGNAL STATE: STATE_TYPE;
CONSTANT s0 : STATE_TYPE := "0000";
CONSTANT s1 : STATE_TYPE := "0001";
CONSTANT s2 : STATE_TYPE := "0010";
CONSTANT s3 : STATE_TYPE := "0011";
CONSTANT s4 : STATE_TYPE := "0100";
CONSTANT s5 : STATE_TYPE := "0101";
CONSTANT s6 : STATE_TYPE := "0110";
CONSTANT s7 : STATE_TYPE := "0111";
CONSTANT s8 : STATE_TYPE := "1000";
begin
UUT_Motor: motor_pwm_clk32kHz Port Map (
clk => clk,
entrada => posMotor,
salida => motorOut);
UUT_Servo: servo_pwm_clk32kHz Port Map (
clk => clk,
pos => posServo,
servo => servoOut);
UUT_ContadorVueltas: Contador_Vueltas Port Map (
clk => clk,
rst => sigReiniciarVueltas,
vueltas => vueltas,
out1 => ir1,
out2 => ir2);
UUT_Revoluciones: revoluciones Port Map(
clk => clk,
vueltasDentroDeCircuito => sigVueltasDentroDeCircuito,
revoluciones => revolucionesPorSeg
);
process(clk, moverCoche)
begin
if (moverCoche = '0') then
Qt <= s0;
sigReiniciarVueltas <= '1';
sigVueltasDentroDeCircuito <= (others => '0');
posServo <= "10000";
posMotor <= "10000";
elsif (clk'event and clk = '1') then
case Qt is
--Quieto
when s0 =>
posServo <= "10000";
posMotor <= "10000";
sigReiniciarVueltas <= '0';
Qt <= s1;
--Recta1
when s1 =>
sigReiniciarVueltas <= '0';
posServo <= "10000";
posMotor <= vMaxCurva; --Min: 10011
sigVueltasDentroDeCircuito <= ("00" & vueltas);
if (unsigned(vueltas) >= unsigned(vueltasRecta)) then
Qt <= s2;
sigReiniciarVueltas <= '1';
elsif (obst = '1') then
Qt <= s8;
else
-- sigVueltasRecta <= vueltasRecta;
Qt <= s1;
end if;
-- Curva1
when s2 =>
sigReiniciarVueltas <= '0';
posServo <= angulo;
posMotor <= vMaxCurva;
sigVueltasDentroDeCircuito <= posInicial + ("00" & vueltas);
if (unsigned(vueltas) >= unsigned(vueltasCurva)) then
sigReiniciarVueltas <= '1';
Qt <= s3;
elsif (obst = '1') then
Qt <= s8;
else
Qt <= s2;
end if;
--Recta2
when s3 =>
sigReiniciarVueltas <= '0';
posServo <= "10000";
posMotor <= vMaxCurva; --Min: 10011
sigVueltasDentroDeCircuito <= posInicial + vueltasCurva + ("00" & vueltas);
if (unsigned(vueltas) >= unsigned(vueltasRecta)) then
sigReiniciarVueltas <= '1';
Qt <= s4;
elsif (obst = '1') then
Qt <= s8;
else
Qt <= s3;
end if;
--Curva2
when s4 =>
sigReiniciarVueltas <= '0';
posServo <= angulo;
posMotor <= vMaxCurva;
sigVueltasDentroDeCircuito <= posInicial + vueltasCurva + vueltasRecta + ("00" & vueltas);
if (unsigned(vueltas) >= unsigned(vueltasCurva)) then
sigVueltasDentroDeCircuito <= (others => '0');
sigReiniciarVueltas <= '1';
Qt <= s4;
elsif (obst = '1') then
Qt <= s8;
else
Qt <= s1;
end if;
--Mantener Quieto
when s5 =>
posMotor <= "10000";
Qt <= s5;
when others =>
if(obst = '1') then
posMotor <= "00000";
--sigReiniciarVueltas <= '0';
Qt <= s8;
else
Qt <= s1;
end if;
end case;
vueltasDentroDeCircuito <= sigVueltasDentroDeCircuito;
vueltasLed <= vueltasRecta;
end if;
end process;
end Behavioral;
While it is possible to perform arithmetic comparison (in this case, <) on a std_logic_vector, it probably isn't best practice, as it is unknown whether the underlying value is signed or unsigned. If you need to do any arithmetic or comparisons, use unsigned or signed types from the numeric_std package.
A good discussion is found here.

VHDL if/else un-findable syntax error

So I am building a divider that divides unsigned 8 bit numbers by 53. It shows the quotient and the remainder as an output. I use one if/else statement to accomplish this task. I am getting syntax error near each if/elseif/else statements just declaring a syntax error, and I CANNOT find the error, where is my syntax error?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity divider is
Port ( input : in STD_LOGIC_VECTOR (7 downto 0);
output : out STD_LOGIC_VECTOR (7 downto 0);
r : out STD_LOGIC_VECTOR ( 7 downto 0));
end divider;
architecture Behavioral of divider is
signal input : unsigned(7 downto 0);
signal n : unsigned(7 downto 0);
signal quotient : unsigned(7 downto 0);
signal remainder : unsigned(7 downto 0);
signal a : unsigned(7 downto 0);
signal b : unsigned(7 downto 0);
signal c : unsigned(7 downto 0);
signal d : unsigned(7 downto 0);
signal zero : unsigned(7 downto 0);
signal one : unsigned(7 downto 0);
signal two : unsigned(7 downto 0);
signal three : unsigned(7 downto 0);
signal four : unsigned(7 downto 0);
signal x : unsigned(7 downto 0);
signal y : unsigned(7 downto 0);
signal z : unsigned(7 downto 0);
signal t : unsigned(7 downto 0);
begin
a <= "11010100"; -- 212
b <= "110011111"; -- 159
c <= "01101010"; -- 106
d <= "00110101"; -- 53
zero <= "0000000"; -- 0
one <= "00000001"; -- 1
two <= "00000010"; -- 2
three <= "00000011"; -- 3
four <= "00000100"; -- 4
x <= n - a; -- input - 212
y <= n - b; -- input - 159
z <= n - c; -- input - 106
t <= n - d; -- input - 53
input <= n;
if (x > zero) then
quotient <= four;
remainder <= n - a;
elsif (y = zero) then
quotient <= three;
remainder <= n - b;
elsif (z > zero) then
quotient <= two;
remainder <= n - c;
elsif (t > zero) then
quotient <= one;
remainder <= n - d;
else
quotient <= zero;
remainder <= n;
end if;
output <= quotient;
r <= remainder;
end behavioral;
This analyzes:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity divider is
port ( input: in std_logic_vector (7 downto 0);
output: out std_logic_vector (7 downto 0);
r: out std_logic_vector ( 7 downto 0)
);
end divider;
architecture behavioral of divider is
-- signal input: unsigned(7 downto 0);
signal n: unsigned(7 downto 0);
signal quotient: unsigned(7 downto 0);
signal remainder: unsigned(7 downto 0);
signal a: unsigned(7 downto 0);
signal b: unsigned(7 downto 0);
signal c: unsigned(7 downto 0);
signal d: unsigned(7 downto 0);
signal zero: unsigned(7 downto 0);
signal one: unsigned(7 downto 0);
signal two: unsigned(7 downto 0);
signal three: unsigned(7 downto 0);
signal four: unsigned(7 downto 0);
signal x: unsigned(7 downto 0);
signal y: unsigned(7 downto 0);
signal z: unsigned(7 downto 0);
signal t: unsigned(7 downto 0);
begin
a <= "11010100"; -- 212 -- get the lengths right
b <= "10011111"; -- 159 -- should these be constants?
c <= "01101010"; -- 106
d <= "00110101"; -- 53
zero <= "00000000"; -- 0
one <= "00000001"; -- 1
two <= "00000010"; -- 2
three <= "00000011"; -- 3
four <= "00000100"; -- 4
x <= n - a; -- input - 212
y <= n - b; -- input - 159
z <= n - c; -- input - 106
t <= n - d; -- input - 53
-- input <= n; -- can't assign inputs
process (x, zero, four, three, n, b, c, d) -- need a process
begin
if x > zero then
quotient <= four;
remainder <= n - a;
elsif y = zero then
quotient <= three;
remainder <= n - b;
elsif z > zero then
quotient <= two;
remainder <= n - c;
elsif t > zero then
quotient <= one;
remainder <= n - d;
else
quotient <= zero;
remainder <= n;
end if;
end process;
output <= std_logic_vector(quotient); -- need type conversion
r <= std_logic_vector(remainder); -- ditto
end architecture behavioral;
You had several string literals who's length did not match their assignment targets.
The if statement needed to be in a process.
There were some missing type conversions.
The rest of the changes are style and readability.
Haven't validated the algorithm it implements.