Есть ли способ определить тип диапазона на основе диапазона неограниченного вектора, объявленного в порте объекта? - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь внедрить универсальный десериализатор в VHDL-2008.(В частности, я стремлюсь к тому, что может быть синтезировано Vivado в режиме VHDL-2008).

Я включил свой текущий код ниже.Объявление порта сущности задает неограниченный std_logic_vector DATA_OUT для десериализованного выходного слова.

Проблема заключается в том, что в этой реализации мне нужно указать CounterType следующим образом, если я хочу иметь возможность обрабатывать 32-битныйслова:

type CounterType is range 0 to 31;

Я не смог придумать, как написать определение CounterType из размера порта DATA_OUT таким образом, чтобы он был действительным VHDL, не говоря уже о способе, который приемлемк компилятору Вивадо.

Есть ли способ сделать это?(Т.е. определить тип диапазона, где диапазон соответствует диапазону фактического параметра без ограничений?)

Если нет, каковы мои варианты, чтобы эта реализация десериализатора была как можно более универсальной, т. Е. Иметь возможностьсоздать экземпляр для разных размеров выходного слова?

(Примечание: я бы предпочел способ, который не добавляет универсальный к интерфейсу объекта, так как он кажется избыточным со спецификацией диапазона DATA_OUT во время создания экземпляра. Но еслииначе это сделать нельзя, меня бы тоже заинтересовали подобные решения.)

library ieee;
use ieee.std_logic_1164.all;

entity deserializer is

    -- The deserializer accepts its single input bit DATA_IN whenever (DATA_IN_VALID and DATA_IN_READY) = '1'.
    -- The deserializer drops its output word DATA_OUT and proceeds whenever (DATA_OUT_VALID and DATA_OUT_READY) = '1'.

    port (
        CLK            : in  std_logic;
        RESET          : in  std_logic;
        DATA_IN        : in  std_logic;
        DATA_IN_VALID  : in  std_logic;
        DATA_IN_READY  : out std_logic;
        DATA_OUT       : out std_logic_vector;
        DATA_OUT_VALID : out std_logic;
        DATA_OUT_READY : in  std_logic
    );

end entity deserializer;


architecture arch of deserializer is

-- This implementation is designed to have no wait states: if a continuous stream of input bits is offered,
-- and the deserializer can offload its output words unimpeded, DATA_IN_READY will always be true, i.e.,
-- we'll never throttle our input; we'll process 1 bit per clock cycle.

type CounterType is range 0 to 31; -- should correspond to the index range of DATA_OUT.

type StateType is record
    -- Internal state.
    counter     : CounterType;
    data_in_bit : std_logic; -- Used to store an input bit while waiting to offload the output word in state (counter == 0).
    -- Output registers.
    data_in_ready  : std_logic;
    data_out       : std_logic_vector(DATA_OUT'range);
    data_out_valid : std_logic;
end record StateType;

constant reset_state : StateType := (
    counter        => 0,
    data_in_bit    => '-',
    data_in_ready  => '1',
    data_out       => (others => '-'),
    data_out_valid => '0'
  );

signal current_state : StateType := reset_state;
signal next_state    : StateType;

begin

    combinatorial: process (all) is
    variable state: StateType;
    begin
        -- Calculate next state based on current state and inputs.
        if RESET = '1' then
            -- Handle synchronous reset.
            state := reset_state;
        else
            -- Start from current state.
            state := current_state;

            if state.counter = 0 then
                -- Note: we may have a pending output, waiting to be accepted.
                if state.data_out_valid = '1' and DATA_OUT_READY = '1' then
                    state.data_out := (others => '-');
                    state.data_out_valid := '0';
                end if;

                if state.data_in_ready = '1' and DATA_IN_VALID = '1' then
                    state.data_in_bit := DATA_IN;
                    state.data_in_ready := '0';
                end if;

                if state.data_out_valid = '0' and state.data_in_ready = '0' then
                    state.data_out(state.data_out'right) := state.data_in_bit;
                    state.data_in_bit := '-';
                    state.counter := state.counter + 1;
                    state.data_in_ready := '1';
                end if;
            else
                if state.data_in_ready = '1'and DATA_IN_VALID = '1' then
                    state.data_out := state.data_out sll 1;
                    state.data_out(state.data_out'right) := DATA_IN;
                    if state.counter = CounterType'high then
                        state.data_out_valid := '1';
                        state.counter := 0;
                    else
                        state.counter := state.counter + 1;
                    end if;
                end if; 
            end if;

        end if;

        -- Schedule next state for update at next rising clock edge.
        next_state <= state;

        -- Drive entity outputs from current state.
        DATA_IN_READY  <= current_state.data_in_ready;
        DATA_OUT       <= current_state.data_out;
        DATA_OUT_VALID <= current_state.data_out_valid;

    end process combinatorial;

    sequential: process (CLK) is
    begin
        if rising_edge(CLK) then
            current_state <= next_state;
        end if;
    end process sequential;

end architecture arch;

1 Ответ

0 голосов
/ 05 декабря 2018

CounterType может иметь размер DATA_OUT'low to DATA_OUT'high.Вместо объявления полностью нового целочисленного типа, который несовместим с предопределенным целочисленным типом, называемым «nteger», вы должны объявить подтип следующим образом:

subtype CounterType is integer range DATA_OUT'low to DATA_OUT'high;

Если инструменты полностью совместимы с VHDL-2008, они должнытакже примите это:

subtype CounterType is integer range DATA_OUT'range;
...