是否有一种简单的方法来实现以下行:
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/