我正在尝试编写一些VHDL代码,其目的是获取一些外部输入信号并将其重定向到某些特定输出。所有信号都由自己的外部时钟驱动。我正在设计和测试这个,所以下面的代码可能不完全准确。
此外,我尝试锁存或缓冲输入端口和输出端口上的输入信号,以确保信号在FPGA内部和外部PCB上具有最大传播时间,以避免时序违规。这是我知道实现这一目标的唯一方法。
现在,关于这个问题。这基本上是一个具有多个时钟的通用架构,所以我使用生成语句来生成不同的进程块(主要是因为我的模拟器拒绝编译代码)。但后来我遇到了多个进程驱动相同信号的问题。
如果我查看input_process_gen,我可以使用generate语句,在这种情况下我会得到多个驱动程序。或者我可以使用循环,但模拟器会抱怨上升沿时钟语句。所以我想知道如何做到这一点。使用已解决的信号是一个好主意吗?它会起作用吗?不过,我不完全确定如何为这些复杂信号编写一个。 VHDL还是新手。
也许有更好的解决方案? 可能还有其他一些事情可以改进,如果是这样的话,我很乐意听到可能的改进。感谢。
library ieee;
use ieee.std_logic_1164.all;
package generic_types is
type signal_array is array (natural range <>, natural range <>) of std_logic;
type port_array is array (natural range <>, natural range <>) of bit;
type clk_array is array (natural range <>) of std_logic;
end package;
library ieee;
use work.generic_types.all;
use ieee.std_logic_1164.all;
entity generic_switch_fabric is
generic (Inputs, Outputs, Bits: Integer);
port
(
clk_in: in clk_array(Inputs - 1 downto 0);
clk_out: out clk_array(Outputs - 1 downto 0);
rst_n: in std_logic;
input: in signal_array(Inputs - 1 downto 0, Bits - 1 downto 0);
output: out signal_array(Outputs - 1 downto 0, Bits - 1 downto 0);
port_switcher: in port_array(Inputs - 1 downto 0, Outputs - 1 downto 0)
);
end entity;
architecture RTL of generic_switch_fabric is
signal clocked_input: signal_array(Inputs - 1 downto 0, Bits - 1 downto 0);
signal clocked_output: signal_array(Outputs - 1 downto 0, Bits - 1 downto 0);
signal clk_out_int: clk_array(Outputs - 1 downto 0);
begin
clk_process_gen: for input in 0 to Inputs - 1 generate
clk_process_gen: for output in 0 to Outputs - 1 generate
clk_process: process(clk_in, port_switcher)
begin
-- Propagate input clocks to output clocks
if (port_switcher(input, output) = '1') then
clk_out_int(output) <= clk_in(input);
else
clk_out_int(output) <= 'Z';
end if;
end process;
end generate;
end generate;
clk_process_fwrd: for output in 0 to Outputs - 1 generate
clk_process: process(clk_out_int)
begin
-- Propagate input clocks to output clocks
clk_out(output) <= clk_out_int(output);
end process;
end generate;
input_process_gen: for input_idx in 0 to Inputs - 1 generate
input_process: process(clk_in)
begin
-- Register on inputs
-- for input_idx in 0 to Inputs - 1 loop
if (rising_edge(clk_in(input_idx))) then
for output_idx in Bits - 1 downto 0 loop
clocked_input(input_idx, output_idx) <= input(input_idx, output_idx);
end loop;
end if;
-- end loop;
end process;
end generate;
output_process_gen: for output_idx in 0 to Outputs - 1 generate
output_process: process(clk_out_int)
begin
-- Register on outputs
if (rising_edge(clk_out_int(output_idx))) then
for input_idx in Bits - 1 downto 0 loop
output(output_idx, input_idx) <= clocked_output(output_idx, input_idx);
end loop;
end if;
end process;
end generate;
-- rst_process: process(rst_n)
-- begin
-- if (rst_n = '0') then
-- clocked_output <= (others => (others => '0'));
-- else
-- clocked_output <= (others => (others => 'Z'));
-- end if;
-- end process;
switcher_generation: for i in 0 to Inputs - 1 generate
switch_process: process(clocked_input, port_switcher) is
begin
clocked_output <= (others => (others => 'Z'));
-- ...For every output to port to output it to...
for j in 0 to Outputs - 1 loop
-- ...If input it supposed to be output to this port...
if (port_switcher(i, j) = '1') then
-- ...Copy all the bits from the input to the output...
for k in 0 to Bits - 1 loop
clocked_output(j, k) <= clocked_input(i, k);
end loop;
end if;
end loop;
end process;
end generate;
end architecture RTL;
答案 0 :(得分:0)
clk_process_gen: for input in 0 to Inputs - 1 generate
clk_process_gen: for output in 0 to Outputs - 1 generate
clk_process: process(clk_in, port_switcher)
begin
-- Propagate input clocks to output clocks
if (port_switcher(input, output) = '1') then
clk_out_int(output) <= clk_in(input);
else
clk_out_int(output) <= 'Z';
end if;
end process;
end generate;
end generate;
这将生成与input
连接的clk_int(output)
个信号。现代FPGA不支持内部逻辑的三态驱动程序,因此“多驱动程序”错误必然会失败。
您需要使用多路复用器方法:
clk_process_gen: for output in 0 to Outputs - 1 generate
clk_process: process(clk_in, port_switcher)
begin
-- Propagate input clocks to output clocks
clk_out_int(output) <= clk_in(port_switcher(output));
end process;
end generate;
这需要更改port_array
:type port_array is array (natural range <>) of natural;
请注意,如果没有时钟专用多路复用器,则不建议使用多路复用时钟,因为它不支持超过2个时钟AFAIK。因此,当您更改配置时,输出会出现偏斜问题,以及潜在的故障。