The VHDL design below is supposed to extract the Nth bits from the four values x_0, x_1, x_2 and x_3 and create a new value at every clock but this is not happening.
Find below the design and the generated output for a few forced values for x_0 = 1100, x_1 = 0100, x_2 = 0010 and x_3 = 1011.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity gen_input is
port (x_0,x_1,x_2,x_3 : in std_logic_vector(3 downto 0);
y : out std_logic_vector(3 downto 0);
clk : std_logic);
end gen_input;
architecture Behavioral of gen_input is
signal i : integer := 0;
begin
inst_process : process (clk,x_3,x_2,x_1,x_0)
begin
if(clk'event and clk='1') then
if(i < 4) then
y <= x_3(i)&x_2(i)&x_1(i)&x_0(i);
i <= i + 1;
else
i <= 0;
end if;
end if;
end process inst_process;
end Behavioral;
The output generated: Output for assigned values of x_0, x_1, x_2 and x_3
1 Answer 1
and create a new value at every clock but this is not happening
The reason this isn't happening, is because your code has a clock cycle where no output is assigned:
if(clk'event and clk='1') then
if(i < 4) then
y <= x_3(i)&x_2(i)&x_1(i)&x_0(i);
i <= i + 1;
else
i <= 0; -- here you have no assignment to y
end if;
end if;
Also, your code would be simpler if you declared i
as a variable
instead of a signal
, which is probably what you mean to do anyway. See this for some discussions on the differences.
This code is probably what you're looking for (as a simulation):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity gen_input is
end gen_input;
architecture Behavioral of gen_input is
signal y : std_logic_vector(3 downto 0);
signal clk : std_logic := '0';
constant x_0 : std_logic_vector(3 downto 0) := b"1100";
constant x_1 : std_logic_vector(3 downto 0) := b"0100";
constant x_2 : std_logic_vector(3 downto 0) := b"0010";
constant x_3 : std_logic_vector(3 downto 0) := b"1011";
begin
clkgen: process
begin
wait for 10 ns;
clk <= not clk;
end process clkgen;
inst_process : process (clk)
variable i : natural range 0 to 3 := 0;
begin
if rising_edge(clk) then
y <= x_3(i) & x_2(i) & x_1(i) & x_0(i);
i := i + 1;
if i = 4 then
i := 0;
end if;
end if;
end process inst_process;
end Behavioral;
Note that, since i
is declared as a variable
within the process, you can increment i
and then immediately check it to see if it should be reset to 0. You could also do this:
if i = 3 then
i := 0;
else
i := i + 1;
end if;
but it's more typing and not necessary. Either way, you will end up with the exact same RTL.
Here's the sim:
-
\$\begingroup\$ And actually, to argue with myself, I probably don’t need the if-statement at all, since variable i will be limited to just 2 bits (for range 0 to 3), and will just roll over naturally. But I couldn’t get the sim to work without explicitly resetting it. Probably this is just a sim setting in Vivado. \$\endgroup\$Blair Fonville– Blair Fonville2018年04月19日 10:55:57 +00:00Commented Apr 19, 2018 at 10:55
clk'event and clk='1
while it would not satisfyrising_edge(clk)
which requires a transition from '0' or 'L' to '1' or 'H' (filtering the parameter value and last value through function To_X01). Note the first non-U value ony_gen
is the second bit value from X_3 - X_0. Please state a question. \$\endgroup\$