Reputation: 501
I'm trying to generate a memory for on FPGA, but I'm having some questions related to how I should approach the stored data. When I'd like to update data, do I need to use a new_q1 signal or not? (like I tried to apply in my code (version 1 and 3)). I was told that I need a new q1 signal (I don't exactly know why) and that I always should have an 'else' statement to prevent 'don't cares'.
Version 1 is the version with a new q1 signal, however, there is no initial value for new_q1. Version 2 is the version I actually started with but I received a comment that this is not the correct approach for some reason I don't quite understand.
Version 3 is the version that is fully working like it was explained to me, however, in my opinion, it is way too much and the synthesizer is rejecting my new_q1 constructions.
What version should I go with and can somembody clarify that what I'm being told is correct or not and why?
Version 1:
entity memory is
port(
clk : in std_logic;
reset : in std_logic;
selector : in std_logic_vector(5 downto 0);
write : in std_logic;
value : out std_logic
);
end memory;
architecture behaviour of memory is
signal q1, new_q1 : std_logic_vector(63 downto 0);
begin
process(clk, reset) is
begin
if( clk'event AND clk = '1') then
if(reset = '1') then
q1 <= (others => '0');
else
q1 <= new_q1;
end if;
end if;
end process;
process(q1) is
if(write = '1') then
new_q1(to_integer(unsigned(selector)) <= '1';
else
new_q1 <= q1;
end if;
end process;
value <= q1(to_integer(unsigned(selector));
end behaviour;
Version 2:
entity memory is
port(
clk : in std_logic;
reset : in std_logic;
selector : in std_logic_vector(5 downto 0);
write : in std_logic;
value : out std_logic
);
end memory;
architecture behaviour of memory is
signal q1 : std_logic_vector(63 downto 0);
begin
process(clk, reset) is
begin
if( clk'event AND clk = '1') then
if(reset = '1') then
q1 <= (others => '0');
else
if(write = '1') then
q1(to_integer(unsigned(selector)) <= '1';
else
....
end if;
end if;
end if;
end process;
value <= q1(to_integer(unsigned(selector));
end behaviour;
Version 3:
entity memory is
port(
clk : in std_logic;
reset : in std_logic;
selector : in std_logic_vector(5 downto 0);
write : in std_logic;
value : out std_logic
);
end memory;
architecture behaviour of memory is
signal q1 : std_logic_vector(63 downto 0);
begin
process(clk, reset) is
begin
if( clk'event AND clk = '1') then
if(reset = '1') then
q1 <= (others => '0');
else
q1 <= new_q1;
end if;
end if;
end process;
process(q1, write) is
if(write = '1') then
if(unsigned(selector) < 63) then
new_q1 <= q1(63 downto to_integer(unsigned(selector))) & '1' & q1(to_integer(unsigned(selector)) downto 0);
else
new_q1 <= '1' & q1(to_integer(unsigned(selector)) downto 0);
end if;
else
new_q1 <= q1;
end if;
end process;
value <= q1(to_integer(unsigned(selector));
end behaviour;
Upvotes: 0
Views: 232
Reputation: 15924
Based on some assumptions about operation, as noted in the port list, a design may look like below. Implementation in a FPGA is likely to be made using flip-flops, and not internal memories, due to size and the special function, so the name memory
may be misleading through.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity memory is
port(
clk : in std_logic;
reset : in std_logic; -- Synchronous, assumed to be applied initially
selector : in std_logic_vector(5 downto 0);
write : in std_logic; -- Write set bit only, synchronous
value : out std_logic -- Read value, asynchronous
);
end memory;
architecture behaviour of memory is
signal q1 : std_logic_vector(63 downto 0);
begin
-- Reset and write set, synchronous
process (clk) is
begin
if (clk'event and clk = '1') then -- Rising clock
if (reset = '1') then -- Reset, synchronous
q1 <= (others => '0'); -- Clear all bits
elsif (write = '1') then -- Write to set for selector bit
q1(to_integer(unsigned(selector))) <= '1'; -- Set single bit
end if;
end if;
end process;
-- Read, asynchronous
value <= q1(to_integer(unsigned(selector))); -- Read single bit
end behaviour;
Upvotes: 1