使用数学表达式的VHDL动态切片

时间:2014-10-12 10:06:14

标签: hardware vhdl slice

是否有一种简单的方法来实现以下行:

DataTX(255-index*8 downto 248-index*8)  <= encoded;

index是一个整数,可以在0到31之间。

DataTx是STD_LOCIC_VECTOR(263 downto 0)。

现在它发出一个错误,说DataTx(263)和DataTx(260)有多个驱动程序,但实际上并没有在这一行中发生。

有没有办法编写这一行或实现它,而无需执行大量的if语句或case语句。

先谢谢你。

编辑: 上面的行放在一个过程中。 同时,DataTx的其他部分在该过程之外设置如下

DataTX(263 downto 261) <= "000" when spi_mode=reading else "001" when spi_mode=writing 
                        else "011" when spi_mode=rxMode  else "101" when spi_mode=txMode;
DataTX(260 downto 256) <= SPI_register;

EDIT2:

DataTX(263 downto 261) <= "000" when spi_mode=reading else "001" when spi_mode=writing 
                        else "011" when spi_mode=rxMode  else "101" when spi_mode=txMode;
DataTX(260 downto 256) <= SPI_register;
-- Set the RF Chan based on input
rf_chan <= RfChans(0) when base_selection="00" else  RfChans(1) when base_selection="01" else
         RfChans(2) when base_selection="10" else  RfChans(3) when base_selection="11";
-- Set the Base Address based on input
base_addr <= Bases(0) when base_selection="00" else  Bases(1) when base_selection="01" else
         Bases(2) when base_selection="10" else  Bases(3) when base_selection="11";
process(clk)
variable s_index : integer range 0 to 31 := 0;
variable e_index : integer range 0 to 31 := 0;
variable r_index : integer range 0 to 31 := 0;
variable counter : integer range 0 to 7 := 0;
begin
    if (rst = '1') then
        ...
    elsif (clk'event and clk='1') then
        case state is
            when setup =>
                case setup_state is
                        -- Some code like this is set here
                        spi_mode <= writing;
                        spi_register <= "10000";
                        DataTX(255 downto 224) <= base_addr;
                        DataTX(223 downto 0) <= (others => '1'); -- Fill with FF
            when idle =>
                ... -- nothing here of relevance
                -- Moves to E_setup
            when E_setup =>
                -- DataTx set here
                spi_mode <= writing;
                spi_register <= "00000";
                SPI_trigger <= '1';
                state <= E_setupd;
            when E_setupd => -- one cycle delay
                SPI_Trigger <= '0';
                        if ((counter = 7) and SS='1') then
                            -- Signals that SPI module has finished
                            state <= E_encode;
                            counter := 0;
                        elsif (counter < 7) then -- Give it some time to start
                            counter := counter +1;
                        end if; 
            when E_encode => 
                encode_input <= SEQUENCE(e_index);
                e_index := e_index +1;
                state <= E_done;
            when E_done =>
                spi_register <= "00000";
                -- Error here
                DataTX(255-index*8 downto 248-index*8)  <= encoded;
                if (e_index = 31) then
                        e_index := 0;
                        state <= E_send;
                else
                    e_index := e_index +1;
                    state <= E_encode;
                end if;
        end case;
    end if;
end process;

1 个答案:

答案 0 :(得分:1)

更新的问题提供了足够的信息来尝试答案。 它归结为什么是&#34;本地静态&#34;即可在不实际执行过程的情况下进行计算,以便可以合成硬件以满足规范。

现在你可能很明显

DataTX(<arbitrary range expression>)  <= encoded;

仅驱动DataTX的选定部分,而不评估<arbitrary range expression>,但合成工具并不那么聪明。因此语言对过程施加了限制,即本地静态&#34;表达式是DataTX的全部,因此该过程驱动所有DataTX

(注意:范围表达式纯粹是根据常量或数字文字,这个限制不适用)

外部作业然后形成您的额外司机,从而产生多个司机&#34;错误。

两个修正:

1)在整个过程中驱动整个DataTX,即在过程中移动其他切片分配......这对我来说看起来像是不洁净的设计

2)分配新信号,例如进程中EncodedTX,并从外部将其分配给正确的DataTX片段

DataTX(255 downto 0) <= EncodedTX;

或更好(更清晰的设计意图)

DataTX <= SPI_Mode_Bits & SPI_Register & Encoded_TX;

SPI_Mode_Bits信号提供合适的声明和分配。

可能还有其他修复,但其中第二个可能是我的第一选择......

鉴于Edit2,我现在相信选项(1)更清晰:例如分配主状态机进程中的额外位,无论如何都是设置SPI_Mode和SPI_Register的位置。您甚至可以为相关的Data_TX片段创建SPI_Register别名。然后,您不需要在SM和支持它之间的外部残差之间进行交叉引用。

例如,请考虑以下声明:

alias SPI_Register : std_logic_vector(4 downto 0) is DataTX(260 downto 256);
subtype SPI_Mode_Type is std_logic_vector(2 downto 0);
alias SPI_Mode     : SPI_Mode_Type is DataTX(263 downto 261);
constant writing   : SPI_Mode_Type := "001"; -- and a few more of these

状态机无需更改,现在将执行Datatx的所有分配,并且可以简单地删除外部分配。