hardware - VHDL 使用数学表达式进行动态切片

标签 hardware vhdl slice

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

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

index 是一个介于 0 到 31 之间的整数。

DataTx 是一个 STD_LOCIC_VECTOR(263 到 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;

编辑2:

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;

最佳答案

更新后的问题提供了足够的信息来尝试回答。 它归结为“本地静态”,即无需实际执行过程即可计算,以便可以合成硬件以满足规范。

现在您可能很明显

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

仅驱动 DataTX 的选定部分让其他人失去动力,而不进行评估<arbitrary range expression> ,但综合工具并不是那么智能。因此,该语言对该过程进行了限制,即“本地静态”表达式是DataTX的全部。所以这个过程驱动所有DataTX .

(注意:如果范围表达式纯粹是常量或数字文字,则此限制不适用)

外部分配会形成额外的驱动程序,从而导致“多个驱动程序”错误。

两个修复:

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 的地方。您甚至可以将 SPI_Register 设置为 Data_TX 相关片的别名。那么您就不需要在 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 的所有分配,并且可以简单地删除外部分配。

关于hardware - VHDL 使用数学表达式进行动态切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26323968/

相关文章:

c - 将一个数组的所有元素存储到另一个数组以便处理

embedded - Poulsbo 系统 Controller 集线器 (US15W) 中 LPC 总线的配置寄存器

vhdl - VHDL 的 IEEE 库中的可合成定点/浮点

VHDL : nested vs. 多个条件中的 If 语句

process - 何时必须将信号插入进程的敏感列表中

numpy - Fortran 相当于 numpy.where() 函数?

tensorflow 通过(不同范围的 2d)切片列表更改/分配矩阵元素值

windows - 如何即时更改我的事件声卡?

arrays - go 垃圾会收集部分 slice 吗?

hardware - 到底是什么中断?