Search code examples
vhdl

Bit shift register vhdl varying size


I'm trying to get two outputs (pulse(0) and pulse(1)) to deliver a short one clock pulse. The latency between these pulses needs to be controlled by some input value. So 0x1 = 1 clock cycle etc.

At the moment, once the trigger switches on, it stays on

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;

<...snip>


architecture rtl of trig_latency is

signal ack : std_logic;
signal s_level : unsigned(pulse'range);
signal s_level_d1 : std_logic;
signal bit_shift : std_logic_vector(addr_width downto 0);
signal latency: integer:=5;


begin
latency <= to_integer(unsigned(in_data(addr_width -1 downto 0))) when addr_width > 0 else 0;
    process(clk)
        begin
            if rising_edge(clk) then
                if ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write = '1' then
                    s_level <= s_level + 1;
                    s_level_d1<=s_level(s_level'left);
                              else
                               s_level<=(others=>'0);


                end if;

                bit_shift <= bit_shift(bit_shift'high-1 downto 0) & (s_level(s_level'left) and (not s_level_d1));
                ipbus_out.ipb_rdata <= (others => '0');
                ack <= ipbus_in.ipb_strobe and not ack; 

                pulse(0) <= s_level(s_level'left) and (not s_level_d1);
                pulse(1)<=bit_shift(latency);

            end if;

    end process;

  ipbus_out.ipb_ack <= ack;
  ipbus_out.ipb_err <= '0';

end rtl;

Solution

  • Why can't you just shift your bits the whole way and ignore the fact that they go above N. The usual VHDL shifter uses the & to concatenate the shifted register with the new value:

    bit_shift <= bit_shift(bit_shift'high-1 downto 0) & s_level;
    

    That should produce your shift register just fine.

    The pulse(1) <= bit_shift(N) ought to work fine.