I'm trying to write some VHDL code whose purpose is take some external input signals and redirect them some specific outputs. All signals are driven by their own external clock. I am in the process of designing and testing this, so the below code may not be entirely accurate.
Also, I try to latch or buffer the input signals on the input ports and on the output ports to ensure the signals have maximum propagation time inside the FPGA and on the external PCB to avoid timing violations. This is the only way I know to achieve this.
Now, on to the problem. This is basically a generic architecture with multiple clocks, so I'm using generate statements to generate different process blocks (mostly because my simulator refuses to compile the code otherwise). But then I have a problem where multiple processes are driving the same signals.
If I look at input_process_gen, I can either use generate statements, in which case I get multiple drivers. Or I can use loops, but then the simulator will complain about the rising edge clock statement. So I was wondering how to do this. Is using resolved signals a good idea? Will it work? I'm not entirely sure how to write one for these complicated signals, though. Still new at VHDL.
Maybe there's some better solution? There are probably other things that could be improved, and if that is the case, I'm open to hear about possible improvements. Thanks.
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;