Experimental Instruction memory adjustment
This commit is contained in:
@@ -78,7 +78,7 @@ BEGIN
|
|||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
ack <= '0';
|
ack <= '0';
|
||||||
else
|
else
|
||||||
if wslvi.stb = '1' and wslvi.cyc = '1' and ack = '0' then
|
if wslvi.stb = '1' and wslvi.cyc = '1' and ack = '0' and out_dmem.ready = '1' then
|
||||||
ack <= '1';
|
ack <= '1';
|
||||||
else
|
else
|
||||||
ack <= '0';
|
ack <= '0';
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ architecture RTL of memdiv is
|
|||||||
|
|
||||||
-- type for the memory signal
|
-- type for the memory signal
|
||||||
type memory_type is array (0 to size - 1) of std_logic_vector(width - 1 downto 0);
|
type memory_type is array (0 to size - 1) of std_logic_vector(width - 1 downto 0);
|
||||||
|
-- type for dmem_write fsm
|
||||||
|
type write_states is (read_old, write_new);
|
||||||
|
|
||||||
-- this function initializes an array of memory_type with the contents of a given file
|
-- this function initializes an array of memory_type with the contents of a given file
|
||||||
-- function from http://myfpgablog.blogspot.de/2011/12/memory-initialization-methods.html
|
-- function from http://myfpgablog.blogspot.de/2011/12/memory-initialization-methods.html
|
||||||
@@ -114,6 +116,11 @@ architecture RTL of memdiv is
|
|||||||
signal dmem_write_fault : std_logic;
|
signal dmem_write_fault : std_logic;
|
||||||
-- fault signal for imem read faults
|
-- fault signal for imem read faults
|
||||||
signal imem_read_fault : std_logic;
|
signal imem_read_fault : std_logic;
|
||||||
|
|
||||||
|
signal old_word : std_logic_vector(width - 1 downto 0);
|
||||||
|
signal in_dmem_reg : core_dmem;
|
||||||
|
signal mem_ready : std_logic;
|
||||||
|
signal write_state : write_states;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
-- fault logic
|
-- fault logic
|
||||||
@@ -276,27 +283,46 @@ begin
|
|||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
dmem_write_fault <= '0';
|
dmem_write_fault <= '0';
|
||||||
elsif (in_dmem.write_en = '1') then
|
|
||||||
dmem_write_fault <= '0';
|
dmem_write_fault <= '0';
|
||||||
|
write_state <= read_old;
|
||||||
|
old_word <= (others => '0');
|
||||||
|
mem_ready <= '1';
|
||||||
|
else
|
||||||
|
case write_state is
|
||||||
|
when read_old =>
|
||||||
wordaddress := to_integer(unsigned(in_dmem.write_addr(in_dmem.write_addr'high downto 2)));
|
wordaddress := to_integer(unsigned(in_dmem.write_addr(in_dmem.write_addr'high downto 2)));
|
||||||
byteaddress := in_dmem.write_addr(1 downto 0);
|
|
||||||
|
|
||||||
if (wordaddress < size) then -- in memory range and no special word
|
if (wordaddress < size) then -- in memory range and no special word
|
||||||
|
in_dmem_reg <= in_dmem;
|
||||||
|
mem_ready <= '1';
|
||||||
|
if (in_dmem.write_en = '1') then
|
||||||
|
write_state <= write_new;
|
||||||
|
mem_ready <= '0';
|
||||||
-- read old word
|
-- read old word
|
||||||
word := memory(wordaddress)(31 downto 0);
|
old_word <= memory(wordaddress)(31 downto 0);
|
||||||
|
end if;
|
||||||
-- modify word
|
else
|
||||||
case in_dmem.write_size is
|
dmem_write_fault <= '1';
|
||||||
|
-- synthesis translate_off
|
||||||
|
assert false report "memory access out of bounds (dmem write at " & integer'image(to_integer(unsigned(in_dmem.write_addr))) & ")" severity error;
|
||||||
|
-- synthesis translate_on
|
||||||
|
end if;
|
||||||
|
when write_new =>
|
||||||
|
wordaddress := to_integer(unsigned(in_dmem_reg.write_addr(in_dmem.write_addr'high downto 2)));
|
||||||
|
byteaddress := in_dmem_reg.write_addr(1 downto 0);
|
||||||
|
word := old_word;
|
||||||
|
write_state <= read_old;
|
||||||
|
mem_ready <= '1';
|
||||||
|
case in_dmem_reg.write_size is
|
||||||
when "00" => -- byte access
|
when "00" => -- byte access
|
||||||
case byteaddress is
|
case byteaddress is
|
||||||
when "00" =>
|
when "00" =>
|
||||||
word(31 downto 24) := in_dmem.write_data(7 downto 0);
|
word(31 downto 24) := in_dmem_reg.write_data(7 downto 0);
|
||||||
when "01" =>
|
when "01" =>
|
||||||
word(23 downto 16) := in_dmem.write_data(7 downto 0);
|
word(23 downto 16) := in_dmem_reg.write_data(7 downto 0);
|
||||||
when "10" =>
|
when "10" =>
|
||||||
word(15 downto 8) := in_dmem.write_data(7 downto 0);
|
word(15 downto 8) := in_dmem_reg.write_data(7 downto 0);
|
||||||
when "11" =>
|
when "11" =>
|
||||||
word(7 downto 0) := in_dmem.write_data(7 downto 0);
|
word(7 downto 0) := in_dmem_reg.write_data(7 downto 0);
|
||||||
when others =>
|
when others =>
|
||||||
-- will not happen in synthesis, but might in simulation
|
-- will not happen in synthesis, but might in simulation
|
||||||
word(7 downto 0) := (others => 'X');
|
word(7 downto 0) := (others => 'X');
|
||||||
@@ -304,11 +330,11 @@ begin
|
|||||||
when "01" => -- halfword access
|
when "01" => -- halfword access
|
||||||
case byteaddress is
|
case byteaddress is
|
||||||
when "00" =>
|
when "00" =>
|
||||||
word(31 downto 16) := in_dmem.write_data(15 downto 0);
|
word(31 downto 16) := in_dmem_reg.write_data(15 downto 0);
|
||||||
when "01" =>
|
when "01" =>
|
||||||
word(23 downto 8) := in_dmem.write_data(15 downto 0);
|
word(23 downto 8) := in_dmem_reg.write_data(15 downto 0);
|
||||||
when "10" =>
|
when "10" =>
|
||||||
word(15 downto 0) := in_dmem.write_data(15 downto 0);
|
word(15 downto 0) := in_dmem_reg.write_data(15 downto 0);
|
||||||
when others =>
|
when others =>
|
||||||
-- memory access exceeds word boundaries
|
-- memory access exceeds word boundaries
|
||||||
dmem_write_fault <= '1';
|
dmem_write_fault <= '1';
|
||||||
@@ -318,7 +344,7 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
when "10" =>
|
when "10" =>
|
||||||
if (byteaddress = "00") then
|
if (byteaddress = "00") then
|
||||||
word := in_dmem.write_data;
|
word := in_dmem_reg.write_data;
|
||||||
else
|
else
|
||||||
-- memory access exceeds word boundaries
|
-- memory access exceeds word boundaries
|
||||||
dmem_write_fault <= '1';
|
dmem_write_fault <= '1';
|
||||||
@@ -334,15 +360,9 @@ begin
|
|||||||
assert false report "memory size not implemented" severity error;
|
assert false report "memory size not implemented" severity error;
|
||||||
-- synthesis translate_on
|
-- synthesis translate_on
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
memory(wordaddress) <= word;
|
memory(wordaddress) <= word;
|
||||||
|
end case;
|
||||||
|
|
||||||
else
|
|
||||||
dmem_write_fault <= '1';
|
|
||||||
-- synthesis translate_off
|
|
||||||
assert false report "memory access out of bounds (dmem write at " & integer'image(to_integer(unsigned(in_dmem.write_addr))) & ")" severity error;
|
|
||||||
-- synthesis translate_on
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process dmem_write;
|
end process dmem_write;
|
||||||
@@ -350,9 +370,11 @@ begin
|
|||||||
-- in synthesis, data is always valid in next clock cycle
|
-- in synthesis, data is always valid in next clock cycle
|
||||||
synthesis_only : if (in_synthesis) generate
|
synthesis_only : if (in_synthesis) generate
|
||||||
out_imem.read_data <= imem_data;
|
out_imem.read_data <= imem_data;
|
||||||
out_imem.ready <= '1';
|
-- out_imem.ready <= '1';
|
||||||
|
out_imem.ready <= mem_ready;
|
||||||
out_dmem.read_data <= dmem_data;
|
out_dmem.read_data <= dmem_data;
|
||||||
out_dmem.ready <= '1';
|
-- out_dmem.ready <= '1';
|
||||||
|
out_dmem.ready <= mem_ready;
|
||||||
end generate synthesis_only;
|
end generate synthesis_only;
|
||||||
|
|
||||||
-- add latency in simulation only
|
-- add latency in simulation only
|
||||||
@@ -360,44 +382,52 @@ begin
|
|||||||
-- synthesis translate_off
|
-- synthesis translate_off
|
||||||
simulation_only : if (in_simulation) generate
|
simulation_only : if (in_simulation) generate
|
||||||
-- instruction memory latency
|
-- instruction memory latency
|
||||||
imem_delay : process is
|
|
||||||
begin
|
|
||||||
wait until imem_data'event;
|
|
||||||
|
|
||||||
-- wait artificial delay
|
|
||||||
if (imem_latency > 0 ns) then
|
|
||||||
-- show not ready-yet data as XX
|
|
||||||
out_imem.ready <= '0';
|
|
||||||
out_imem.read_data <= (others => 'X');
|
|
||||||
wait for imem_latency;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- output data
|
|
||||||
out_imem.read_data <= imem_data;
|
out_imem.read_data <= imem_data;
|
||||||
|
out_imem.ready <= mem_ready;
|
||||||
-- now we're ready
|
|
||||||
out_imem.ready <= '1';
|
|
||||||
end process imem_delay;
|
|
||||||
|
|
||||||
-- data memory latency
|
|
||||||
dmem_delay : process is
|
|
||||||
begin
|
|
||||||
wait until dmem_data'event;
|
|
||||||
|
|
||||||
-- wait artificial delay
|
|
||||||
if (dmem_latency > 0 ns) then
|
|
||||||
-- show not ready-yet data as XX
|
|
||||||
out_dmem.ready <= '0';
|
|
||||||
out_dmem.read_data <= (others => 'X');
|
|
||||||
wait for dmem_latency;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- output data
|
|
||||||
out_dmem.read_data <= dmem_data;
|
out_dmem.read_data <= dmem_data;
|
||||||
|
out_dmem.ready <= mem_ready;
|
||||||
|
|
||||||
-- now we're ready
|
-- imem_delay : process is
|
||||||
out_dmem.ready <= '1';
|
-- begin
|
||||||
end process dmem_delay;
|
-- wait until imem_data'event;
|
||||||
|
--
|
||||||
|
-- -- wait artificial delay
|
||||||
|
-- if (imem_latency > 0 ns) then
|
||||||
|
-- -- show not ready-yet data as XX
|
||||||
|
-- out_imem.ready <= '0';
|
||||||
|
-- out_imem.read_data <= (others => 'X');
|
||||||
|
-- wait for imem_latency;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- -- output data
|
||||||
|
-- out_imem.read_data <= imem_data;
|
||||||
|
--
|
||||||
|
-- -- now we're ready
|
||||||
|
-- -- out_imem.ready <= '1';
|
||||||
|
-- out_dmem.ready <= mem_ready;
|
||||||
|
-- end process imem_delay;
|
||||||
|
--
|
||||||
|
-- -- data memory latency
|
||||||
|
-- dmem_delay : process is
|
||||||
|
-- begin
|
||||||
|
-- wait until dmem_data'event;
|
||||||
|
--
|
||||||
|
-- -- wait artificial delay
|
||||||
|
-- if (dmem_latency > 0 ns) then
|
||||||
|
-- -- show not ready-yet data as XX
|
||||||
|
-- out_dmem.ready <= '0';
|
||||||
|
-- out_dmem.read_data <= (others => 'X');
|
||||||
|
-- wait for dmem_latency;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- -- output data
|
||||||
|
-- out_dmem.read_data <= dmem_data;
|
||||||
|
--
|
||||||
|
-- -- now we're ready
|
||||||
|
-- -- out_dmem.ready <= '1';
|
||||||
|
-- out_dmem.ready <= mem_ready;
|
||||||
|
-- end process dmem_delay;
|
||||||
|
|
||||||
end generate simulation_only;
|
end generate simulation_only;
|
||||||
-- synthesis translate_on
|
-- synthesis translate_on
|
||||||
|
|||||||
Reference in New Issue
Block a user