I'm having problems with getting this code to work:
if(s="00") then
f3 <= x and not(y);
elsif(s="11") then
f3 <= not(y) xor x;
else
f3 <= x or y;
end if;
where:
f3 : out std_logic_vector(2 downto 0);
x, y : in std_logic_vector(2 downto 0);
s : in std_logic_vector(1 downto 0)
Of course I can't really rely on compilation error messages, because they aren't specific about the error. Thanks in advance!
The whole code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cw1 is
port(
f0, f2 : out std_logic;
f3 : out std_logic_vector(2 downto 0);
a0, a1, a2, a3, a4 : in std_logic;
x, y : in std_logic_vector(2 downto 0);
s : in std_logic_vector(1 downto 0)
);
end entity;
architecture A of cw1 is
signal s1 : std_logic_vector(3 downto 0);
signal a : std_logic_vector(2 downto 0);
begin
s1 <= a0 & a1 & a2 & a3;
a <= a0 & a1 &a2;
with a select
f2 <= not(a4) when "000",
a3 when "001"|"010"|"101"|"111",
a4 or not(a3) when "011"|"100",
'-' when "110",
'X' when others;
if s="00" then
f3 <= x and not(y);
elsif s="11" then
f3 <= not(y) xor x;
else
f3 <= x or y;
end if;
end A;
If you want to use if, you had to put it in a process:
process(s, x, y)
begin
if(s="00") then
f3 <= x and not(y);
elsif(s="11") then
f3 <= not(y) xor x;
else
f3 <= x or y;
end if;
end process;
Related
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.
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.
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.
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
Whats the reverse function of x XOR (x/2)?
Is there a system of rules for equation solving, similar to algebra, but with logic operators?
Suppose we have a number x of N bits. You could write this as:
b(N-1) b(N-2) b(N-3) ... b(0)
where b(i) is bit number i in the number (where 0 is the least significant bit).
x / 2 is the same as x shifted left 1 bit. Let's assume unsigned numbers. So:
x / 2 = 0 b(N-1) b(N-2) ... b(1)
Now we XOR x with x / 2:
x ^ (x / 2) = b(N-1)^0 b(N-2)^b(N-1) b(N-3)^b(N-2) ... b(0)^b(1)
Note that the rightmost bit (the most significant bit) of this is b(N-1)^0 which is b(N-1). In other words, you can get bit b(N-1) from the result immediately. When you have this bit, you can calculate b(N-2) because the second bit of the result is b(N-2)^b(N-1) and you already know b(N-1). And so on, you can compute all bits b(N-1) to b(0) of the original number x.
I can give you an algorithm in bits:
Assuming you have an array of n bits:
b = [b1 .. bn] // b1-bn are 0 or 1
The original array is:
x0 = b0
x1 = b1 ^ x0
x2 = b2 ^ x1
or in general
x[i] = b[i] ^ x[i-1]
Assume Y = X ^ (X / 2)
If you want to find X, do this
X = 0
do
X ^= Y
Y /= 2
while Y != 0
I hope it helps!
I know it's an old topic, but I stumbled upon the same question, and I found out a little trick. If you have n bits, instead of requiring n bits operations (like the answer by Jesper), you can do it with log2(n) number operations :
Suppose that y is equal to x XOR (x/2) at the beginning of the program, you can do the following C program :
INPUT : y
int i, x;
x = y;
for (i = 1; i < n; i <<= 1)
x ^= x >> i;
OUTPUT : x
and here you have the solution.
">>" is the right bit shift operation. For example the number 13, 1101 in binary, if shifted by 1 on the right, will become 110 in binary, thus 13 >> 1 = 6. x >> i is equivalent to x / 2^i (division in the integers, of course)
"<<" is the left bit shift operation (i <<= 1 is equivalent to i *= 2)
Why does it work ? Let's take as example n = 5 bits, and start with y = b4 b3 b2 b1 b0 (in binary : in the following x is written in binary also, but i is written in decimal)
Initialisation :
x = b4 b3 b2 b1 b0
First step : i = 1
x >> 1 = b4 b3 b2 b1 so we have
x = b4 b3 b2 b1 b0 XOR b3 b2 b1 b0 = b4 (b3^b4) (b2^b3) (b1^b2) (b0^b1)
Second step : i = 2
x >> 2 = b4 (b3^b4) (b2^b3) so we have
x = b4 (b3^b4) (b2^b3) (b1^b2) (b0^b1) XOR b4 (b3^b4) (b2^b3) = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3)
Third step : i = 4
x >> 4 = b4 so we have
x = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3) XOR b4 = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3^b4)
Then i = 8, which is more than 5, we exit the loop.
And we have the desired output.
The loop has log2(n) iterations because i starts at 1 and is multiplied by 2 at each step, so for i to reach n, we have to do it log2(n) times.