C
Chris Maryan
Guest
I've googled around but haven't seen a good generic and flexible way
of writing a mux followed by a synchronous output. I've come up with
code that's correctly interpreted as a mux by synplify, but it's a bit
sketchy. Can anyone please enlighten me as to the right way of doing
this:
The following seems to be accepted by synplify as a mux followed by a
register, but it seems logically incorrect:
constant : width := 16;
signal wr_en : std_logic;
signal addr : std_logic_vector(addr_width downto 0);
signal addr_int : integer;
....
addr_int <= conv_integer(addr);
mux_and_reg : process (clk)
begin
if rising_edge(clk) then
if wr_en ='1' then
for i in 0 to log2(addr_width) loop
if i = addr_int then
data_out <= data_in((i+1)*width-1 downto i*width);
end if;
end loop;
end if;
end if;
end process;
I would expect the loop to get unrolled and something weird to happen
relating to the assignment (something like catching only the last
value of i).
Plan B was to do this:
mux_and_reg : process (clk)
begin
if rising_edge(clk) then
if wr_en ='1' then
data_out <= data_in((addr_int+1)*width-1 downto addr_int*width);
end if;
end if;
end process;
But this seems to infer shift registers, which makes sense.
So what is the right way to get a mux followed by a register? All of
the standard examples focus on a hard coded address width and a select
statement. How do I do this with a flexible for-loop or for-generate?
Thanks,
Chris
of writing a mux followed by a synchronous output. I've come up with
code that's correctly interpreted as a mux by synplify, but it's a bit
sketchy. Can anyone please enlighten me as to the right way of doing
this:
The following seems to be accepted by synplify as a mux followed by a
register, but it seems logically incorrect:
constant : width := 16;
signal wr_en : std_logic;
signal addr : std_logic_vector(addr_width downto 0);
signal addr_int : integer;
....
addr_int <= conv_integer(addr);
mux_and_reg : process (clk)
begin
if rising_edge(clk) then
if wr_en ='1' then
for i in 0 to log2(addr_width) loop
if i = addr_int then
data_out <= data_in((i+1)*width-1 downto i*width);
end if;
end loop;
end if;
end if;
end process;
I would expect the loop to get unrolled and something weird to happen
relating to the assignment (something like catching only the last
value of i).
Plan B was to do this:
mux_and_reg : process (clk)
begin
if rising_edge(clk) then
if wr_en ='1' then
data_out <= data_in((addr_int+1)*width-1 downto addr_int*width);
end if;
end if;
end process;
But this seems to infer shift registers, which makes sense.
So what is the right way to get a mux followed by a register? All of
the standard examples focus on a hard coded address width and a select
statement. How do I do this with a flexible for-loop or for-generate?
Thanks,
Chris