trigger with arbitrary width - eventtrigger

Well, I'm trying to make a module in VHDL language, so far I have the internal clock (100MHz) and a control signal called IN (std_logic), and I need an output signal OUT (std_logic) of arbitrary width, said wide I want to control counting the clock rising_edge, I don't have a good programming base, that's why I'm stuck with this, if anyone can help me I thank you
  I enclose an illustrative image of how I wish to have the output, where delta / \ is an arbitrary interval that does not depend on the IN input, when IN goes low, the OUT signal must remain on until the counter finishes its purpose..
https://imgur.com/a/NoPZZjP

So you basically what to create an off delay?
Note: VHDL 2008 migth apply (my usual language)
entity off_delay is
generic(
n : natural : 2 -- off delay
);
port(
clk : in std_logic;
a : in std_logic;
b : out std_logic
);
end entity;
clk _/¯\__/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\
a _____/¯¯¯\________________________________
b _________/¯¯¯¯¯¯¯¯¯¯¯¯\___________________
architecture synkron of off_delay is
signal delay: std_logic_vector(n downto 0); -- 1+n cycles out signal
begin
b <= delay(0);
process(clk)
begin
if rising_edge(clk) then
delay <= (others => '1') when a else ('0' & delay(delay'left downto 1));
end if;
end process;
end architecture;
clk _/¯\__/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\
a _____/¯¯¯\_____________________________
b _____/¯\¯\¯¯¯¯¯¯¯¯¯¯\___________________
architecture asynkron of off_delay is
signal delay: std_logic_vector(n-1 downto 0); -- n cycles off delay
begin
b <= delay(0) or a;
process(clk)
begin
if rising_edge(clk) then
delay <= (others => '1') when a else ('0' & delay(delay'left downto 1));
end if;
end process;
end architecture;
Note: The asynkron solution will be dependent on stable a as it will be susceptible to glitches.
Note: The asynkron solution will introduce a delta delay that might be hard to debug
Note: Those are the simplest soulutions. To get technical a SR latch could be implemented to set by a in an asynkron fassion and reset by the synkron delay line. OBS Latches are strongly adviced against in fpga design!

Here is another solution which use more ressources with a low width but less with a high width and with width as an input instead of generic :
entity top is
port
(
i_rst : in std_logic;
i_clk : in std_logic;
i_din : in std_logic;
i_width : in std_logic_vector(7 downto 0);
o_dout : out std_logic
);
end top;
architecture Behavioral of top is
signal counter : unsigned(7 downto 0);
signal oe : std_logic;
begin
process(i_clk)
begin
if i_rst = '1' then
counter <= (others => '0');
oe <= '0';
elsif rising_edge(i_clk) then
if oe = '1' then
counter <= counter + 1;
if counter = unsigned(i_width) - 1 then
counter <= (others => '0');
oe <= '0';
end if;
elsif i_din = '1' then
if unsigned(i_width) > x"01" then
counter <= counter + 1;
oe <= '1';
end if;
end if;
end if;
end process;
o_dout <= oe or i_din;
end Behavioral;
But as Halfow told you, use combinational just before the output makes your module very sensitive to glitches.

Related

Rising Edge Led Counter Problems in VHDL

I'm new to fpga and VHDL in general (I'm using a fpga aprox. 2 weeks now). I am trying to create a project that lights up LEDs in order. First of all I made a falling edge detector for the button. And then I created a std_logic_vector for LEDs. But I can't detect a signal change in fallen edge detection. Because of that I can't change LED state. There is my testbench for simulation. I don't have any idea what's going on. Thanks for your answers and sorry for my bad English.
Code:
library ieee;
use ieee.std_logic_1164.all;
entity sequential_led is
end sequential_led;
architecture seq_led of sequential_led is
signal clk : std_logic := '0';
--signal rst : std_logic := '1';
--signal rstb : std_logic := '1';
signal i : natural := 0;
signal dus_next : std_logic := '0';
signal dusen : std_logic := '0';
signal button : std_logic := '0';
signal led : std_logic_vector(7 downto 0);
begin
clk <= not clk after 1 ns;
button <= not button after 2 ns;
falling:
process begin
if rising_edge(clk) then
dus_next <= button;
end if;
wait for 100 ns;
end process falling;
dusen <= (not button) and dus_next;
led_changes:
process begin
if dusen = '1' then
i <= i + 1;
if i = 7 then
i <= 0;
end if;
end if;
led(7-i) <= '0';
led(i) <= '1';
wait for 100 ns;
end process led_changes;
end architecture;
UPDATE: First of all very big thanks to DomasAquinas and Martin Thompson! After 3 days of work, I finally finished my little LED project.
Change: I've made sure all of processes has a sensivity trigger.
For falling process I've included 'clk' signal for sensivity.
For led_change process I've included 'dusen' signal for sensivity.
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sequential_led is
port(
clk : in std_logic;
button : in std_logic;
led : out std_logic_vector(7 downto 0) := (others => '0')
);
signal dus_next : std_logic;
signal i : natural range 0 to 7;
signal dusen : std_logic := '0';
end sequential_led;
architecture seq_led of sequential_led is
begin
falling:
process(clk) begin
if rising_edge(clk) then
dus_next <= button;
end if;
end process falling;
dusen <= (not button) and dus_next;
led_changes:
process(dusen) begin
if dusen = '1' then
i <= i + 1;
if i = 7 then
i <= 0;
end if;
led(i) <= '1';
led(i+7) <= '0';
end if;
end process led_changes;
end architecture;

Behavioral into FlipFlop Structural

In this code, when reset equals 1 the s becomes 1000 and when reset equals 0 the s becomes 0100 then 0010 then 0001 and it starts all over again with 1000 as the start value, only if the clock is up.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_behav is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_behav;
architecture behav of clock_behav is
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
s<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
s<="0100";
shift_counter := 2;
elsif(shift_counter =2) then
s<="0010";
shift_counter := 3;
elsif(shift_counter =3) then
s<="0001";
shift_counter := 0;
else
s<="1000";
shift_counter := 1;
end if;
end if;
end if;
end process;
end behav;
I want to create this
With FlipFlops as you can see, one Set and 3 Reset. But, I struggle to move from behavioral into structural, because in VHDL we can't have in process port maps. Of course I tried many things, as you can see below, but it's impossible to recreate it with flipflops if the port maps are not inside the process. As you can clearly understand , my knowledge about VHDL it's not that great. Also, I want you to tell me if I did right when I changed the flipflop D and Q types, it was std_logic and I changed it to std_logic_vector . I did this for the purpose of this exercise.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_structural is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_structural;
architecture behavior of clock_structural is
signal t,t1,t2,t3 : std_logic_vector (3 downto 0);
component flipflop_new
port
(D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0));
end component;
component flipflop_set
port
(D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0));
end component;
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
t<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
shift_counter := 2;
elsif(shift_counter =2) then
shift_counter := 3;
elsif(shift_counter =3) then
shift_counter := 0;
else
shift_counter := 1;
end if;
end if;
end if;
end process;
FFS1: flipflop_set port map(t,clock,reset,t1);
s<=t1;
FFR1: flipflop_new port map(t1,clock, reset,t2);
s<=t2;
FFR2: flipflop_new port map(t2,clock, reset,t3);
s<=t3;
FFR3: flipflop_new port map(t3,clock, reset,s);
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_new is
port ( D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0)
);
end flipflop_new;
architecture behavior of flipflop_new is
begin
process(CLK)
begin
if CLR='0' then null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_set is
port ( D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0)
);
end flipflop_set;
architecture behavior of flipflop_set is
begin
process(CLK_s)
begin
if CLR_s='1' then null;
elsif RISING_EDGE(CLK_s) then
Q_s <= D_s;
end if;
end process ;
end behavior ;
There are several things to change or improve. A structural VHDL model should describe your schematic, which you don't really do.
First, why do you have shift_counter in your structural? You don't need that process.
Second, you instantiate 4 of your flip-flop entity which are each 4 bits wide, while your schematic's has 4 flip-flops. Basically, you instantiate a total of 16 registers when you need 4. Why is your flip-flop model 4 bits wide? It should be a single bit.
Third, look at your flip-flop description:
process(CLK)
begin
if CLR='0' then
null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
Does it seems what a flip-flop do? The Q <= D when the clock rises is fine, but does nothing happens when the clr of the flip-flop is active? Your output should reset/set in that case, which is not what your VHDL describe.
Another error is that you assign your output s 3 times. s must be assigned once, but you can assign bit individually like s(0) <= t1.
Finally, you don't describe the feedback. The output of your last flip-flop is s, while the input of the first flip-flop is t. From your schematic, they should be connected together.

Counter Not Testing As Expected? [VHDL]

I'm trying to make a 32 bit counter in VHDL. Below is my code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY counter32 IS
PORT (en, clk, clr: IN STD_LOGIC;
count: OUT STD_LOGIC_VECTOR(4 DOWNTO 0));
END counter32;
ARCHITECTURE rtl OF counter32 IS
SIGNAL count_result: STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
counter32: PROCESS(clk, clr)
BEGIN
count <= "00000"; --Initialize counter to all zeroes
IF (clr = '0') THEN
count_result <= "00000";
ELSIF (clk = '1' and clk'EVENT) THEN
IF (en = '1') THEN
count <= STD_LOGIC_VECTOR(unsigned(count_result) + 1);
count <= STD_LOGIC_VECTOR(count_result);
ELSIF (count_result = "11111") THEN
count_result <= "00000";
END IF;
END IF;
END PROCESS counter32;
END rtl;
My test bench code is here:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter32_tb is
end counter32_tb;
architecture io of counter32_tb is
component counter32 is
port(en,clk,clr:in std_logic; count:out std_logic_vector(4 downto 0));
end component;
for all: counter32 use entity work.counter32(rtl);
signal en,clk,clr:std_logic;
signal count:std_logic_vector(4 downto 0);
begin
count <= "00000";
g0: counter32 port map(en,clk,clr,count);
p0: process
begin
en <= '1';
clk <= '0';
clr <= '1';
wait for 10ns;
en <= '1';
clk <= '1';
clr <= '1';
wait for 10ns;
en <= '1';
clk <= '0';
clr <= '1';
wait for 10ns;
en <= '1';
clk <= '1';
clr <= '1';
wait for 10ns;
en <= '1';
clk <= '0';
clr <= '1';
wait for 10ns;
en <= '1';
clk <= '1';
clr <= '0';
end process;
end io;
Whenever I test, however, an addition of 1 gives a 'U' STD_LOGIC value and a red bar in testing, as you can see here:
Any idea what the matter is? I'm really confused!
Any idea what the matter is?
Your waveform doesn't match your test bench stimulus.
There are three assignments to the signal count which appears to show in your waveform (at the test bench level). An initial assignment to "00000", and two conditional assignments. The bouncing back and forth is caused by the process sensitity to clk, bouncing back to "00000" on the following edge of clock using the first assignment statement.
In a process statement the last assignment is the one that takes effect. You're writing it to "00000" and changing that to count_result conditionally based on the positive edge of clock. Note that you aren't actually loading count with count_result + 1 either, the next assignment provides the current value of count_result. While we're on the subject the type conversion to std_logic_vector isn't needed either, count_result is already a std_logic_vector.
The unknown (red) 'flash' at the clock edge is because you haven't actually cleared count_result. The only event on clr is from 'U' to '1' and causes no clear.
The vhdl design code is not functional as a counter.
This:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter32 is
port (
en, clk, clr: in std_logic;
count: out std_logic_vector(4 downto 0)
);
end counter32;
architecture rtl of counter32 is
signal count_result: std_logic_vector(4 downto 0);
begin
counter: process(clk, clr)
begin
if clr = '0' then
count_result <= (others => '0');
elsif clk = '1' and clk'event and en = '1' then
count_result <= std_logic_vector(unsigned(count_result) + 1);
end if;
end process;
count <= count_result;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
entity counter32_tb is
end entity;
architecture foo of counter32_tb is
signal en: std_logic:= '0';
signal clr: std_logic:= '1';
signal clk: std_logic:= '0';
signal count: std_logic_vector (4 downto 0);
begin
DUT: entity work.counter32
port map (
en => en,
clk => clk,
clr => clr,
count => count
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 720 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
clr <= '0';
en <= '1';
wait for 20 ns;
clr <= '1';
wait for 20 ns;
wait for 20 ns;
wait for 20 ns;
wait for 20 ns;
wait for 20 ns;
en <= '0';
wait for 20 ns;
en <= '1';
wait;
end process;
end architecture;
Gives this:
The reason no end cases are necessary in the count arithmetic are due to how the unsigned "+" operator works, calling unsigned_add in the package body for numeric_std. End counts are something you need to worry about in scalar increments.
The purpose behind having count (mode out) and count_result, is to allow the count value to be read internally for versions of VHDL predating IEEE Std 1076-2008. For a -2008 compliant simulation you should be only using count. Note the above simulation shown will run on earlier versions of VHDL.
You could likewise make count_result a variable.
And I trust you're aware based on signal array sizes this is a 5 bit counter and not a 32 bit counter. Converting to the latter is relatively easy.

VHDL simulates fine, but doesn't act the same in hardware

I've written a few components to move a stepper motor back and forwards. I've simulated it in modelsim and it works as expected, but it won't work the same in hardware at all.
Basically I have a motor driving component, which takes a command of number of steps, hold time and speed and then performs the movement. Then I have the control_arbiter, which is just an intermediate bridge that connects components wanting access to the motors and the motor driving components.
Finally I have a 'search pattern' component, which basically issues the commands to move the motor back and forth.
My problem is that I can't seem to get direction to change when it's running in hardware, regardless of it working in simulation.
Any help with this would be greatly appreciated
Motor driver:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity motor_ctrl is
port( clk: in std_logic;
-- Hardware ports
SCLK, CW, EN: out std_logic; -- stepper driver control pins
-- Soft ports
Speed, steps: in integer;
dir: in std_logic; -- 1 = CW; 0 = CCW;
hold_time: in integer; -- if > 0, steppers will be held on for this many clock periods after moving
ready: out std_logic; -- indicates if ready for a movement
activate: in std_logic; -- setting activate starts instructed motion.
pos_out: out integer -- starts at 2000, 180deg = 200 steps, 10 full rotations trackable
);
end motor_ctrl;
architecture behavioural of motor_ctrl is
type action is (IDLE, HOLD, MOVE);
signal motor_action: action := IDLE;
signal clk_new: std_logic;
signal position: integer := 2000;
signal step_count: integer := 0;
signal drive: boolean := false;
begin
-- Clock divider
clk_manipulator: entity work.clk_divide port map(clk, speed, clk_new);
-- Drive motors
with drive select
SCLK <= clk_new when true,
'0' when false;
pos_out <= position;
process(clk_new)
-- Counter variables
variable hold_count: integer := 0;
begin
if rising_edge(clk_new) then
case motor_action is
when IDLE =>
-- reset counter vars, disable the driver and assert 'ready' signal
hold_count := 0;
step_count <= 0;
drive <= false;
EN <= '0';
ready <= '1';
-- When activated, start moving and de-assert ready signal
if(activate = '1') then
motor_action <= MOVE;
end if;
when HOLD =>
-- Stop the step clock signal
ready <= '0';
drive <= false;
-- Hold for given number of clock periods before returning to idle state
if(hold_count = hold_time) then
motor_action <= IDLE;
end if;
-- increment counter
hold_count := hold_count + 1;
when MOVE =>
-- Enable driver, apply clock output and set direction
ready <= '0';
EN <= '1';
drive <= true;
CW <= dir;
-- track the position of the motor
--if(dir = '1') then
-- position <= steps + step_count;
--else
-- position <= steps - step_count;
--end if;
-- Increment count until complete, then hold/idle
if(step_count < steps-1) then
step_count <= step_count + 1;
else
motor_action <= HOLD;
end if;
end case;
end if;
end process;
end behavioural;
Control_arbiter:
entity Control_arbiter is
port (clk: in std_logic;
EN, RST, CTRL, HALF, SCLK, CW: out std_logic_vector(2 downto 0)
-- needs signals for levelling and lock
);
end Control_arbiter;
architecture fsm of Control_arbiter is
type option is (INIT, SEARCH);
signal arbitration: option := INIT;
-- Motor controller arbiter signals
-- ELEVATION
signal El_spd, El_stps, El_hold, El_pos: integer;
signal El_dir, El_rdy, El_run: std_logic;
-- Search signals
signal search_spd, search_stps, search_hold: integer;
signal search_dir, search_Az_run, search_El_run: std_logic := '0';
-- status
signal lock: std_logic := '0';
begin
-- Motor controller components
El_motor: entity work.motor_ctrl port map(clk, SCLK(0), CW(0), EN(0),
El_spd, El_stps, El_dir, El_hold, El_rdy, El_run);
-- Search component
search_cpmnt: entity work.search_pattern port map( clk, '1', search_dir, search_stps, search_spd, search_hold,
El_rdy, search_El_run);
process(clk, arbitration)
begin
if rising_edge(clk) then
case arbitration is
when INIT =>
-- Initialise driver signals
EN(2 downto 1) <= "11";
CW(2 downto 1) <= "11";
SCLK(2 downto 1) <= "11";
RST <= "111";
CTRL <= "111";
HALF <= "111";
-- Move to first stage
arbitration <= SEARCH;
when SEARCH =>
-- Map search signals to motor controllers
El_dir <= search_dir;
El_stps <= search_stps;
El_spd <= search_spd;
El_hold <= search_hold;
El_run <= search_El_run;
-- Pass control to search
-- Once pointed, begin search maneuvers
-- map search signals to motor controllers
-- set a flag to begin search
-- if new pointing instruction received, break and move to that position (keep track of change)
-- On sensing 'lock', halt search
-- return to holding that position
end case;
end if;
end process;
end fsm;
Search Pattern:
entity search_pattern is
generic (step_inc: unsigned(7 downto 0) := "00010000"
);
port (clk: in std_logic;
enable: in std_logic;
dir: out std_logic;
steps, speed, hold_time: out integer;
El_rdy: in std_logic;
El_run: out std_logic
);
end search_pattern;
architecture behavioural of search_pattern is
type action is (WAIT_FOR_COMPLETE, LATCH_WAIT, MOVE_EL_CW, MOVE_EL_CCW);
signal search_state: action := WAIT_FOR_COMPLETE;
signal last_state: action := MOVE_EL_CCW;
begin
hold_time <= 1;
speed <= 1;
steps <= 2;
process(clk)
begin
if rising_edge(clk) then
-- enable if statement
case search_state is
when LATCH_WAIT =>
-- Make sure a GPMC has registered the command before waiting for it to complete
if(El_rdy = '0') then -- xx_rdy will go low if a stepper starts moving
search_state <= WAIT_FOR_COMPLETE; -- Go to waiting state and get ready to issue next cmd
end if;
when WAIT_FOR_COMPLETE =>
-- Wait for the movement to complete before making next
if(El_rdy = '1') then
-- Choose next command based on the last
if last_state = MOVE_EL_CCW then
search_state <= MOVE_EL_CW;
elsif last_state = MOVE_EL_CW then
search_state <= MOVE_EL_CCW;
end if;
end if;
when MOVE_EL_CW =>
dir <= '1';
El_run <= '1';
last_state <= MOVE_EL_CW;
search_state <= LATCH_WAIT;
when MOVE_EL_CCW =>
dir <= '0';
El_run <= '1';
last_state <= MOVE_EL_CCW;
search_state <= LATCH_WAIT;
when others =>
null;
end case;
-- else step reset on not enable
end if;
end process;
end behavioural;
Sim: http://i.imgur.com/JAuevvP.png
scanning quickly through your code, there are some things that you should change for synthesis:
1) clock divider: make your motor_driver process sensitive to clk instead of clk_new. to divide the clock, generate a one-clock-cycle enable signal every n clocks. the begin of the process could look as follows:
process(clk)
...
begin
if rising_edge(clk) then
if enable='1' then
case motor_action is
...
2) initializations of the form
signal position: integer := 2000;
only work for simulations but don't work for synthesis. for initialization in synthesis use a reset signal within the process.
3) add to all your state machines a "when others" clause, where the state is set to a defined value (e.g. search_state<=INIT).

Design of "simple" VHDL module still drives me mad

Thanks to all your input, I implemented your suggestions, however the problem remains the same. The result in simulation works fine, but the hardware
outputs something different. Just to briefly recap, I have two ctrl signals that determine the behaviour of the entity:
GET (ctrl = "00000000") sets register tx to input of op1
SH1_L (ctrl = "00000001") res := (op1 << 1) | tx;
tx := tx >> 31;
Here is the VHDL code:
library ieee;
use ieee.std_logic_1164.all;
entity test is
port
(
op1 : in std_logic_vector(31 downto 0); -- Input operand
ctrl : in std_logic_vector(7 downto 0); -- Control signal
clk : in std_logic; -- clock
res : out std_logic_vector(31 downto 0) -- Result
);
end;
architecture rtl of test is
type res_sel_type is (GET, SH1_L);
constant Z : std_logic_vector(31 downto 0) := (others => '0');
signal res_sel : res_sel_type;
signal load : std_logic := '0';
signal shl : std_logic := '0';
signal tx : std_logic_vector(31 downto 0) := (others => '0');
signal inp1 : std_logic_vector(31 downto 0) := (others => '0');
begin
dec_op: process (ctrl, op1)
begin
res_sel <= GET;
load <= '0';
shl <= '0';
inp1 <= ( others => '0');
case ctrl is
-- store operand
when "00000000" =>
inp1 <= op1;
load <= '1';
res_sel <= GET;
-- 1-bit left-shift with carry
when "00000001" =>
inp1 <= op1;
shl <= '1';
res_sel <= SH1_L;
when others =>
-- Leave default values
end case;
end process;
sel_out: process (res_sel, inp1, tx)
begin
case res_sel is
when SH1_L =>
res <= ( inp1(30 downto 0) & '0' ) or tx;
when others =>
res <= (others => '0');
end case;
end process;
sync: process(clk)
begin
if clk'event and clk = '1' then
if load = '1' then
tx <= op1;
elsif shl = '1' then
tx <= Z(30 downto 0) & op1(31);
end if;
end if;
end process;
end rtl;
TESTPROGRAM
GET 0 (this sets tx <= 0 )
SH1_L 0xfedcba90 exp. output: 0xfdb97520 act. output = 0xfdb97521
SH1_L 0x7654321f exp. output: 0xeca8643f act. output = 0xeca8643f
SH1_L 0x71234567 exp. output: 0xe2468ace act. output = 0xe2468ace
As you can see, the last bit is wrong for the first SH1_L operation. The first SH1_L operation produces a carry for the NEXT SH1_L operation since
the MSB is set to one of the input, however, it seems that this carry is already considered in the current SH1_L operation, which is wrong (tx should be zero).
I checked the synthesis report and there are no latches, so I am a bit clueless and almost desperate what is going wrong here. I use Xilinx ISE 12.1 for
synthesis, could there be a problem because I do not have a reset signal in my architecture, that the wrong kind of latches are instantiated?
Many thanks for further helpful comments to solve this issue,
Patrick
Unlike RTL simulation, real-life timing of inputs and clocks is not ideal. For example, the clock tree might have a longer delay than input buffers or vice versa. Did you take this into account?