type reg_t is array(0 to OUTPUTS-1) of std_logic_vector(31 downto 0);
signal enable : reg_t;
-signal invert : reg_t;
+signal invert : std_logic_vector(INPUTS-1 downto 0);
+
+signal stretch_inp : std_logic_vector(INPUTS-1 downto 0);
+
+
+signal inp_inv : std_logic_vector(INPUTS-1 downto 0);
+signal inp_long : std_logic_vector(INPUTS-1 downto 0);
+signal inp_long_reg : std_logic_vector(INPUTS-1 downto 0);
-signal inp_reg : std_logic_vector(INPUTS-1 downto 0);
signal output_i: std_logic_vector(OUTPUTS-1 downto 0);
+
+signal inp_reg : std_logic_vector(INPUTS-1 downto 0);
signal out_reg : std_logic_vector(OUTPUTS-1 downto 0);
begin
tmp := to_integer(unsigned(ADDR_IN(4 downto 1)));
if WRITE_IN = '1' then
ACK_OUT <= '1';
- if ADDR_IN(5) = '0' and tmp < OUTPUTS then
- case ADDR_IN(0) is
- when '0' => enable(tmp) <= DATA_IN;
- when '1' => invert(tmp) <= DATA_IN;
+ if ADDR_IN(5) = '0' and ADDR_IN(0) = '0' and tmp < OUTPUTS then
+ enable(tmp) <= DATA_IN;
+ elsif ADDR_IN(5) = '1' then
+ case ADDR_IN(2 downto 0) is
+ when "010" => stretch_inp <= DATA_IN(INPUTS-1 downto 0);
+ when "100" => invert <= DATA_IN(INPUTS-1 downto 0);
end case;
else
NACK_OUT <= '1';
end if;
elsif READ_IN = '1' then
ACK_OUT <= '1';
- if ADDR_IN(5) = '0' and tmp < OUTPUTS then
- case ADDR_IN(0) is
- when '0' => DATA_OUT <= enable(tmp);
- when '1' => DATA_OUT <= invert(tmp);
+ if ADDR_IN(5) = '0' and ADDR_IN(0) = '0' and tmp < OUTPUTS then
+ DATA_OUT <= enable(tmp);
+ elsif ADDR_IN(5) = '1' then
+ case ADDR_IN(2 downto 0) is
+ when "000" => DATA_OUT(INPUTS-1 downto 0) <= inp_reg; DATA_OUT(31 downto INPUTS) <= (others => '0');
+ when "001" => DATA_OUT(OUTPUTS-1 downto 0) <= out_reg; DATA_OUT(31 downto OUTPUTS) <= (others => '0');
+ when "010" => DATA_OUT(INPUTS-1 downto 0) <= stretch_inp; DATA_OUT(31 downto INPUTS) <= (others => '0');
+ when "100" => DATA_OUT(INPUTS-1 downto 0) <= invert; DATA_OUT(31 downto INPUTS) <= (others => '0');
+ when others => NACK_OUT <= '1'; ACK_OUT <= '0';
end case;
- elsif ADDR_IN(5) = '0' and tmp >= OUTPUTS then
+ else
NACK_OUT <= '1';
ACK_OUT <= '0';
- else
- case ADDR_IN(1 downto 0) is
- when "00" => DATA_OUT(INPUTS-1 downto 0) <= inp_reg; DATA_OUT(31 downto INPUTS) <= (others => '0');
- when "01" => DATA_OUT(OUTPUTS-1 downto 0) <= out_reg; DATA_OUT(31 downto OUTPUTS) <= (others => '0');
- when others => NACK_OUT <= '1'; ACK_OUT <= '0';
- end case;
end if;
end if;
end process;
+
+inp_inv <= INPUT xor invert;
+inp_long <= (inp_inv or inp_long) and not inp_long_reg;
+inp_long_reg <= inp_long when rising_edge(CLK);
+
+
gen_outs : for i in 0 to OUTPUTS-1 generate
- output_i(i) <= or_all((INPUT xor invert(i)(INPUTS-1 downto 0)) and enable(i)(INPUTS-1 downto 0));
+ output_i(i) <= or_all((((inp_long or inp_long_reg) and stretch_inp) or (inp_inv and not stretch_inp)) and enable(i)(INPUTS-1 downto 0));
end generate;
inp_reg <= INPUT when rising_edge(CLK);